我有一个主类,该类显示带有按钮的窗口。单击按钮后,将调用一个子类(包含while循环),该子类在单独的窗口中显示“是”。我不确定执行while循环后为什么会显示子窗口。随附的代码供您参考。非常感谢您的帮助。
class test1(QtWidgets.QMainWindow):
def __init__(self):
super (test1, self).__init__()
test1.setGeometry(self, 20, 20, 400, 250)
btn = QtWidgets.QPushButton("Add", self)
btn.clicked.connect(self.Check)
btn.resize(btn.sizeHint())
btn.move(10, 170)
self.show()
def Check(self):
self.test2=test2()
class test2(QtWidgets.QMainWindow):
def __init__(self):
super (test2, self).__init__()
test2.setGeometry(self,20, 20, 450, 100)
self.label = QtWidgets.QLabel("Yay",self)
self.show()
a=50
b=60
x=True
time.sleep(5)
while (x):
if a!=b:
a+=1
else:
x=False
def run():
app = QtWidgets.QApplication(sys.argv)
GUI = test1()
GUI.show()
sys.exit(app.exec_())
run()
答案 0 :(得分:0)
GUI驻留在事件循环中,该循环允许获取键盘,鼠标,逻辑等各种元素的数据并更新GUI的状态,因此如果GUI被冻结,不会允许其正常工作。在这种情况下,阻塞事件循环的是睡眠,而while不会干预,因为它的执行时间不到1毫秒。
因此,占用大量时间的任务必须在GUI的不同线程中执行,以避免被阻塞,但是在您这种情况下,可以用QTimer代替睡眠。
总而言之,睡眠使GUI冻结了。我看到该代码具有教育意义,因此我将向您展示几个选项:
threading.Thread():
import threading
# ...
class test2(QtWidgets.QMainWindow):
def __init__(self):
super (test2, self).__init__()
test2.setGeometry(self,20, 20, 450, 100)
self.label = QtWidgets.QLabel("Yay",self)
self.show()
threading.Thread(target=self.foo, daemon=True).start()
def foo(self):
time.sleep(5)
a=50
b=60
x=True
while x:
if a != b:
a += 1
print(a)
else:
x = False
QTimer + QEventLoop:
class test2(QtWidgets.QMainWindow):
def __init__(self):
super (test2, self).__init__()
test2.setGeometry(self,20, 20, 450, 100)
self.label = QtWidgets.QLabel("Yay",self)
self.show()
loop = QtCore.QEventLoop()
QtCore.QTimer.singleShot(5*1000, loop.quit)
loop.exec_()
a=50
b=60
x=True
while x:
if a != b:
a += 1
print(a)
else:
x = False
QTimer:
class test2(QtWidgets.QMainWindow):
def __init__(self):
super (test2, self).__init__()
test2.setGeometry(self,20, 20, 450, 100)
self.label = QtWidgets.QLabel("Yay",self)
self.show()
QtCore.QTimer.singleShot(5*1000, self.foo)
def foo(self):
a=50
b=60
x=True
while x:
if a != b:
a += 1
print(a)
else:
x = False
作为一般结论,如果建议的时间大于建议在另一个线程中执行的时间,则在GUI线程中执行的任务应少于30ms。在循环中的每个任务都满足上述要求但又有很多迭代的情况下,可以使用QTimer定期执行循环中的任务。