Python 使用GUI执行ping命令

Python 使用GUI执行ping命令,python,python-3.x,pyqt,pyqt5,Python,Python 3.x,Pyqt,Pyqt5,在用PyQt5编写GUI应用程序时,我遇到了奇怪的(对我来说)行为。 当我想打开一个信息窗口并在它完全加载后开始做另一件事时。我注意到信息窗口在下一个代码块完成之前不会完全加载 这就是它的外观 复制此不需要的行为的代码 from PyQt5.QtWidgets import QApplication,QMessageBox import sys import os app = QApplication(sys.argv) box = QMessageBox() box.setText("Te

在用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()函数,我会使用进程或线程来解决问题,但如果可能的话,我希望确保窗口完全加载,然后进行下一个过程

Python版本3.7.0

PyQt5 5.12.1版作为一个选项。试试看:

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())

虽然S.Nick和Guimoute的解决方案似乎有效,但事实是,它只让窗口显示了一瞬间,但如果你想与它互动,你会看到它被冻结,例如尝试移动窗口以检查它。
os.system()
任务正在阻塞,因此必须在另一个线程中执行

导入操作系统
导入系统
从PyQt5.qtwidts导入QApplication、QMessageBox
导入线程
app=QApplication(sys.argv)
box=QMessageBox()
box.setText(“文本”)
box.show()
def任务():
操作系统(“ping 8.8.8.8”)
threading.Thread(target=task,daemon=True).start()
#或者threading.Thread(target=os.system,args=(“ping 8.8.8.8”),daemon=True.start()
sys.exit(app.exec_())
或使用QProcess:

导入系统 导入操作系统 从PyQt5.qtwidts导入QApplication、QMessageBox 从PyQt5.QtCore导入QProcess app=QApplication(sys.argv) box=QMessageBox() box.setText(“文本”) box.show() _readyReadStandardOutput()上的def: 打印(process.readAllStandardOutput().data().decode(),end=”“) process=QProcess() 进程启动(“ping”,[“8.8.8.8”]) process.readyReadStandardOutput.connect(在\u readyReadStandardOutput上) sys.exit(app.exec_()) 更新
导入操作系统
导入系统
从PyQt5导入QtCore、QtWidgets
类PingObject(QtCore.QObject):
finished=QtCore.pyqtSignal()
@QtCore.pyqtSlot()
def启动(自):
操作系统(“ping 8.8.8.8”)
self.finished.emit()
如果名称=“\uuuuu main\uuuuuuuu”:
app=qtwidts.QApplication(sys.argv)
box=QtWidgets.QMessageBox()
box.setText(“文本”)
box.show()
thread=QtCore.QThread()
thread.start()
ping=PingObject()
ping.moveToThread(线程)
QtCore.QTimer.singleShot(0,ping.start)
loop=QtCore.QEventLoop()
ping.finished.connect(循环.退出)
loop.exec()
打印(“完成ping”)
sys.exit(app.exec_())
另一个选项:

import os
import sys
from PyQt5 import QtCore, QtWidgets


class Thread(QtCore.QThread):
    def run(self):
        response = os.popen("ping 8.8.8.8")
        for line in response.readlines():
            print(line)


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

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

    thread = Thread()
    thread.start()
    ret = app.exec_()
    thread.quit()
    thread.wait()
    sys.exit(ret)

以下是一个单线解决方案:

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())
从PyQt5.qtwidts导入QApplication,QMessageBox
导入系统
导入操作系统
app=QApplication(sys.argv)
box=QMessageBox()
box.setText(“文本”)
box.show()

QApplication.processEvents()#您没有将父项添加到消息框中,这可能是因为?我在设置父项时遇到了相同的错误。@AdrianBaczyński检查我的答案,因为S.Nick的答案不正确在这一行“QTimer.singleShot(20,osSystem)”结束后等待的最佳方式是什么?例如,您的方法不正确,它阻止窗口移动窗口仍被阻止,但其行为与我想要的最接近ProcessEvents只是一个虚假的解决方案,例如,尝试移动窗口时,您将看到窗口已被阻止frozen@eyllanescOP希望在执行其他任务之前将窗口完全加载,没有关于窗口响应的规范。@Guimoute IMHO窗口的响应能力是所有GUI的要求,没有人喜欢冻结的GUI。所以它不需要显式,你的程序的线程版本对我不起作用,它以同样的方式阻塞。当窗口在屏幕上移动时,QProcess()方法正在阻止os.system。@AdrianBaczyński有多奇怪,你在不修改代码的情况下执行我的代码吗?可能您修改得不正确。您是对的,线程上的“join()”函数导致了这种行为。@AdrianBaczyński join阻止了抛出线程的线程,因此现在阻止的不是os.system(),而是join,在GUI中,您不应该使用join,因为eventloop实现了类似的功能。您能告诉我如何使用您的线程代码等待线程工作完成吗?