Python PyQt5显示窗口后运行函数
我想在GUI显示后调用一个函数。如果我在init中运行函数,它将阻止gui显示,直到它完成Python PyQt5显示窗口后运行函数,python,python-3.x,pyqt,pyqt5,Python,Python 3.x,Pyqt,Pyqt5,我想在GUI显示后调用一个函数。如果我在init中运行函数,它将阻止gui显示,直到它完成 class MyApp(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): QtWidgets.QMainWindow.__init__(self) Ui_MainWindow.__init__(self) self.setupUi(self) self.functio
class MyApp(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.function() #waits for this to finish until gui displayed
def function(self):
self.guiBox.setValue(initData)
#inits stuff, takes 5 seconds
该函数通过串行端口初始化设备。。。它需要几秒钟,并且需要gui属性和更新gui显示框。耗时的任务正在阻塞,这与gui上的自然工作方式背道而驰,一个选项是使用
qApp.processEvents()
,例如:
def function(self):
self.guiBox.setValue(initData)
code1
QtWidgets.qApp.processEvents()
code2
QtWidgets.qApp.processEvents()
...
我建议使用QThreads,尤其是在“函数”中执行大量其他操作的情况下。这个示例不是在PyQt中执行线程的唯一方法,但我认为最好使用一个能够在线程和主gui之间来回传递数据的示例
import os
import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
from PyQt5.QtCore import QUrl, QEventLoop, QThread, QObject, pyqtSlot, pyqtSignal
from PyQt5.QtWebEngineWidgets import QWebEngineView
class time_consuming_function(QObject):
def __init__(self, widget):
super(time_consuming_function, self).__init__()
self.widget = widget
self.run_trigger.connect(self.run)
run_trigger = pyqtSignal(int, int)
@pyqtSlot(int, int)
def run(self, int1, int2):
print("In Time Consuming Function")
for i in range(100000000):
i*i
print("Finished with Time Consuming Function")
self.widget.someTrigger.emit([1, 2, 3])
class WebPage(QWebEngineView):
def __init__(self):
QWebEngineView.__init__(self)
self.load(QUrl("https://www.google.com"))
self.loadFinished.connect(self._on_load_finished)
self.someTrigger.connect(self.gui_response)
self.thread = QThread()
self.thread.start()
self.consume = time_consuming_function(self)
self.consume.moveToThread(self.thread)
self.consume.run_trigger.emit(1,1)
someTrigger = pyqtSignal(list)
def _on_load_finished(self):
print("Finished Loading")
def gui_response(self, data):
print("Responding to GUI: ", str(data))
if __name__ == "__main__":
app = QApplication(sys.argv)
web = WebPage()
web.show()
sys.exit(app.exec_())
我想说,不使用thread和related的最简单方法是验证显示窗口的最后一个事件是否已执行,然后调用您的方法
你会有这样的东西:
import sys
from PyQt5.QtCore import QEvent
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QMainWindow
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setFixedSize(500, 500)
self.move(300, 50)
def print_1_bi(self):
for i in range(10**9): print(i)
def event(self, event):
if event.type() == QEvent.InputMethodQuery:
self.print_1_bi()
return super(MainWindow, self).event(event)
if __name__ == "__main__":
app = QApplication(sys.argv)
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
注意:请记住,即使UI已经显示,您的应用程序仍将等待您的方法完成,如果出现问题,您必须使用其他答案中告诉您的流程。添加单次触发计时器1毫秒和事后调用功能
class MyApp(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
QTimer.singleShot(1,self.function) #waits for this to finish until gui displayed
def function(self):
self.guiBox.setValue(initData)
#inits stuff, takes 5 seconds
你应该说更多关于函数在做什么,你是否需要在主窗口中使用它(它是否引用了一些属性)?这与我需要的正好相反。我想先显示GUI,然后运行函数。这很好,谢谢!如果没有其他人提出更好的解决方案,我会在几天内接受答案。如果函数已知,它可以给出更好的解决方案。我认为更好的解决方案应该是独立于函数中发生的事情的解决方案。。。我应该能够使用function()或function2(),而不必在每个函数中显式处理gui事件。我的函数打开串行连接,发送命令,然后读取数据,并在spinbox中向GUI显示数据。我知道您正在搜索的是,对我来说,最好的解决方案是使用最少资源(内存和/或时间)执行任务的解决方案P