Вы должны понимать следующее выражение:
Example().setWindowTitle("Window")
эквивалентно:
obj = Example()
obj.setWindowTitle("Window")
То есть вы создаете другой объект-пример, отличный от ex = Example()
, и этот объект создает другой объект myclass2
, а этот другой объект myclass2
создает еще один пример, и явно создается бесконечный цикл.
Еще одна вещь, которая в будущем может вызвать у вас проблемы, это установить одно и то же имя для разных вещей, хотя в этом случае это не проблема, но в будущем это может вызвать проблемы, код, на который я ссылаюсь:
self.myclass2 = myclass2()
Например, рекомендуется, чтобы классы начинались с заглавных букв.
Другая ошибка, которая действительна только в Qt, заключается в том, что GUI нельзя создавать или обрабатывать в потоке, отличном от основного потока. Таким образом, вы не можете изменить заголовок непосредственно в другой ветке, но есть 2 способа:
1. QMetaObject::invokeMethod(...)
Но для этого мы должны передать GUI через свойство:
class Example(QWidget):
def __init__(self):
super().__init__()
self.myclass2 = MyClass()
self.myclass2.gui = self
self.myclass2.start()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QIcon('web.png'))
self.show()
class MyClass(QThread):
def run(self):
while True:
time.sleep(.1)
print(" in thread \n")
QMetaObject.invokeMethod(self.gui, "setWindowTitle", Qt.QueuedConnection, Q_ARG(str, "Window"))
2. сигналы и слоты
class Example(QWidget):
def __init__(self):
super().__init__()
self.myclass2 = MyClass()
self.myclass2.titleChanged.connect(self.setWindowTitle)
self.myclass2.start()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QIcon('web.png'))
self.show()
class MyClass(QThread):
titleChanged = pyqtSignal(str)
def run(self):
while True:
time.sleep(.1)
print(" in thread \n")
self.titleChanged.emit("Window")
PLUS:
Вы не должны изменять графический интерфейс непосредственно из потока, а отправлять данные через сигнал:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class Example(QtWidgets.QWidget):
def __init__(self):
super().__init__()
lay = QtWidgets.QVBoxLayout(self)
le = QtWidgets.QLineEdit()
lay.addWidget(le)
self.myclass2 = MyClass()
self.myclass2.titleChanged.connect(self.setWindowTitle)
self.myclass2.infoChanged.connect(le.setText) # <-- connect signal
self.myclass2.start()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QtGui.QIcon('web.png'))
self.show()
class MyClass(QtCore.QThread):
titleChanged = QtCore.pyqtSignal(str)
infoChanged = QtCore.pyqtSignal(str) # <-- create signal
def run(self):
counter = 0
while True:
QtCore.QThread.msleep(100)
print(" in thread \n")
self.titleChanged.emit("Window")
self.infoChanged.emit("{}".format(counter)) # <-- emit signal
counter += 1
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())