在PyQt5中编写GUI应用程序时,遇到奇怪的行为(对我而言)。 当我想打开一个信息窗口并在完全加载后开始做另一件事时。我注意到在完成下一个代码块之前,信息窗口不会完全加载。
这就是它的样子
可重现此不良行为的代码
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
答案 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())