使用图形用户界面执行ping命令

2024-05-15 05:05:44 发布

您现在位置:Python中文网/ 问答频道 /正文

在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类型类,行为都是相同的。你知道吗

我想这种行为是因为操作系统()函数,我将使用进程或线程来解决问题,但如果可能的话,我希望确保窗口已完全加载,然后进行下一个过程。你知道吗

Python版本3.7.0

PyQt5版本5.12.1


Tags: 代码fromimport版本box信息app应用程序
3条回答

虽然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

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

另一种选择:

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

作为一种选择。试试看:

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

相关问题 更多 >

    热门问题