Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PyQt5显示窗口后运行函数_Python_Python 3.x_Pyqt_Pyqt5 - Fatal编程技术网

Python PyQt5显示窗口后运行函数

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

我想在GUI显示后调用一个函数。如果我在init中运行函数,它将阻止gui显示,直到它完成

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