Issue
I'm learning Python, version 3.7 with PyQT5 (Qt Designer)
I'm trying to define the value of a label using modules, in window 1 it calls the function and it works, but when I open window 2 and click the button it triggers the function but passes the self of the current window (window 2) where there is no label , generating the following error:
Traceback (most recent call last):
File "\template\config.py", line 18, in returnMain
fun1(self)
File "\modulos\functions.py", line 7, in fun1
lbl = int(self.ui.lblTest.text())
AttributeError: 'Ui_window2' object has no attribute 'lblTest'
Preciso que ele use na função o self da window 1.
I replicated the error in small files, it works until you click the button in the second window that gives the described error.
Here is the structure of the codes in the directory:
Follow the files.
run.py (Used to start the program)
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
import sys
from template.main import MainScreen
if __name__ == "__main__":
app = QApplication(sys.argv)
main = MainScreen()
main.show()
sys.exit(app.exec_())
gui/window1.py (janela principal)
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_window1(object):
def setupUi(self, win1):
win1.setObjectName("win1")
win1.resize(297, 219)
self.centralwidget = QtWidgets.QWidget(win1)
self.centralwidget.setObjectName("centralwidget")
self.btnConfig = QtWidgets.QPushButton(self.centralwidget)
self.btnConfig.setGeometry(QtCore.QRect(110, 150, 75, 23))
self.btnConfig.setObjectName("btnConfig")
self.lblTest = QtWidgets.QLabel(self.centralwidget)
self.lblTest.setGeometry(QtCore.QRect(120, 70, 47, 13))
self.lblTest.setObjectName("lblTest")
win1.setCentralWidget(self.centralwidget)
self.retranslateUi(win1)
QtCore.QMetaObject.connectSlotsByName(win1)
def retranslateUi(self, win1):
_translate = QtCore.QCoreApplication.translate
win1.setWindowTitle(_translate("win1", "Window 1"))
self.btnConfig.setText(_translate("win1", "Open config"))
self.lblTest.setText(_translate("win1", "0"))
gui/window2.py (settings window)
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_window2(object):
def setupUi(self, win2):
win2.setObjectName("win2")
win2.resize(222, 241)
self.centralwidget = QtWidgets.QWidget(win2)
self.centralwidget.setObjectName("centralwidget")
self.btnReturn = QtWidgets.QPushButton(self.centralwidget)
self.btnReturn.setGeometry(QtCore.QRect(70, 120, 75, 23))
self.btnReturn.setObjectName("btnReturn")
win2.setCentralWidget(self.centralwidget)
self.retranslateUi(win2)
QtCore.QMetaObject.connectSlotsByName(win2)
def retranslateUi(self, win2):
_translate = QtCore.QCoreApplication.translate
win2.setWindowTitle(_translate("win2", "Window 2"))
self.btnReturn.setText(_translate("win2", "Return Main"))
modulos/functions.py (where will the functions be)
from PyQt5.QtWidgets import *
from template import main
def fun1(self):
lbl = int(self.ui.lblTest.text())
lbl = (lbl+1)
self.ui.lblTest.setText(str(lbl))
template/config.py (where I will handle the settings)
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from gui.window2 import *
from modulos.functions import fun1
class ConfigScreen(QMainWindow):
def __init__(self,*args,**argsv):
super(ConfigScreen,self).__init__(*args,**argsv)
self.ui = Ui_window2()
self.ui.setupUi(self)
self.ui.btnReturn.clicked.connect(self.returnMain)
def returnMain(self):
fun1(self)
self.close()
template/main.py (main program module)
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from gui.window1 import *
from template.config import ConfigScreen
from modulos.functions import fun1
class MainScreen(QMainWindow):
def __init__(self,*args,**argsv):
super(MainScreen,self).__init__(*args,**argsv)
self.ui = Ui_window1()
self.ui.setupUi(self)
self.ui.btnConfig.clicked.connect(self.openConfig)
fun1(self)
def openConfig(self):
self.config = ConfigScreen()
self.config.show()
Solution
There are plenty of different ways you could fix this. Here is a possible solution, trying to maintain the existing structure as much as possible. Emit a custom signal from ConfigScreen to communicate with MainScreen when return was requested, and connect its slot to fun1(self)
.
class ConfigScreen(QMainWindow):
returnRequested = QtCore.pyqtSignal()
def __init__(self,*args,**argsv):
super(ConfigScreen,self).__init__(*args,**argsv)
self.ui = Ui_window2()
self.ui.setupUi(self)
self.ui.btnReturn.clicked.connect(self.returnMain)
def returnMain(self):
self.returnRequested.emit()
self.close()
class MainScreen(QMainWindow):
def __init__(self,*args,**argsv):
super(MainScreen,self).__init__(*args,**argsv)
self.ui = Ui_window1()
self.ui.setupUi(self)
self.ui.btnConfig.clicked.connect(self.openConfig)
fun1(self)
def openConfig(self):
self.config = ConfigScreen()
self.config.returnRequested.connect(lambda: fun1(self))
self.config.show()
Also functions.py does not need from template import main
.
Answered By - alec
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.