PyQt5窗口未完全加载

时间:2019-04-24 06:57:26

标签: python python-3.x pyqt5

在PyQt5中编写GUI应用程序时,遇到奇怪的行为(对我而言)。 当我想打开一个信息窗口并在完全加载后开始做另一件事时。我注意到在完成下一个代码块之前,信息窗口不会完全加载。

这就是它的样子

enter image description here

可重现此不良行为的代码

from PyQt5.QtWidgets import QApplication,QMessageBox
import sys
import os
app = QApplication(sys.argv)

box = QMessageBox()
box.setText("Text")
box.show()
os.system("ping 8.8.8.8 ")


sys.exit(app.exec())

无论我使用QMessegBox,在另一个类中继承它还是编写自己的QMeesgeBox类型类,其行为都是相同的。

我猜这是由于os.system()函数而导致的,因此我将使用Process或Thread来解决此问题,但如果可能的话,我想确保窗口已完全加载,然后执行下一个步骤正在发生。

Python版本3.7.0

PyQt5版本5.12.1

3 个答案:

答案 0 :(得分:1)

尽管S.Nick和Guimoute的解决方案似乎有效,但现实情况是,它仅使窗口显示了片刻,但如果您要与之交互,您将看到它已冻结,例如尝试移动窗口检查它。 os.system()任务正在阻塞,因此必须在另一个线程中执行

import os
import sys
from PyQt5.QtWidgets import QApplication,QMessageBox

import threading
app = QApplication(sys.argv)

box = QMessageBox()
box.setText("Text")
box.show()

def task():
    os.system("ping 8.8.8.8 ") 
threading.Thread(target=task, daemon=True).start()
# or threading.Thread(target=os.system, args=("ping 8.8.8.8 ",), daemon=True).start()
sys.exit(app.exec())

或使用QProcess:

import sys
import os
from PyQt5.QtWidgets import QApplication,QMessageBox
from PyQt5.QtCore import QProcess

import threading
app = QApplication(sys.argv)

box = QMessageBox()
box.setText("Text")
box.show()

def on_readyReadStandardOutput():
    print(process.readAllStandardOutput().data().decode(), end="")

process = QProcess()
process.start("ping", ["8.8.8.8"])
process.readyReadStandardOutput.connect(on_readyReadStandardOutput)
sys.exit(app.exec())

更新

import os
import sys
from PyQt5 import QtCore, QtWidgets


class PingObject(QtCore.QObject):
    finished = QtCore.pyqtSignal()

    @QtCore.pyqtSlot()
    def start(self):
        os.system("ping 8.8.8.8")
        self.finished.emit()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    box = QtWidgets.QMessageBox()
    box.setText("Text")
    box.show()
    thread = QtCore.QThread()
    thread.start()
    ping = PingObject()
    ping.moveToThread(thread)
    QtCore.QTimer.singleShot(0, ping.start)
    loop = QtCore.QEventLoop()
    ping.finished.connect(loop.quit)
    loop.exec_()
    print("finished ping")
    sys.exit(app.exec_())

答案 1 :(得分:1)

这是单行解决方案:

from PyQt5.QtWidgets import QApplication,QMessageBox
import sys
import os
app = QApplication(sys.argv)

box = QMessageBox()
box.setText("Text")
box.show()
QApplication.processEvents() # <------------ this one
os.system("ping 8.8.8.8 ")

sys.exit(app.exec())

答案 2 :(得分:0)

作为一个选项。试试吧:

import sys
import os
from PyQt5.QtWidgets import QApplication,QMessageBox
from PyQt5.QtCore import QTimer

app = QApplication(sys.argv)

box = QMessageBox()
box.setText("Text")
box.show()

def osSystem():
    os.system("ping 8.8.8.8 ") 

QTimer.singleShot(20, osSystem )

#os.system("ping 8.8.8.8 ")


sys.exit(app.exec())

enter image description here