如何使用Qthread类从pyqt5对话框执行ping程序?

时间:2019-07-08 02:03:49

标签: python pyqt pyqt5 qthread

我请求帮助在不冻结对话框的情况下运行Windows ping命令。以下代码将运行ScannerDialog,但是在执行ping命令时对话框窗口将冻结。我认为最好的方法是在Scanner_Dialog对象上方构建一个Qthread类,但是我不了解PYQT5如何使用线程。我想我很亲密,但是有人可以修复我的代码以向我展示在PYQt中进行线程化的正确方法吗?

我试图运行各种功能并创建各种类。我试图将类放入另一个模块,然后调用该模块。

正在运行的ping程序在下面,但是对话框冻结

ScannerDialog.py


import os
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtNetwork import QHostAddress
from PyQt5.QtCore import QRegExp, QThread
from PyQt5.QtGui import QRegExpValidator


class Scanner_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(254, 176)
        self.groupBox = QtWidgets.QGroupBox(Dialog)
        self.groupBox.setGeometry(QtCore.QRect(10, 10, 231, 151))
        self.groupBox.setObjectName("groupBox")
        self.widget = QtWidgets.QWidget(self.groupBox)
        self.widget.setGeometry(QtCore.QRect(20, 30, 199, 107))
        self.widget.setObjectName("widget")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.widget)
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.ip_label = QtWidgets.QLabel(self.widget)
        self.ip_label.setObjectName("ip_label")
        self.verticalLayout_2.addWidget(self.ip_label)
        self.ports_label = QtWidgets.QLabel(self.widget)
        self.ports_label.setObjectName("ports_label")
        self.verticalLayout_2.addWidget(self.ports_label)
        self.types_label = QtWidgets.QLabel(self.widget)
        self.types_label.setObjectName("types_label")
        self.verticalLayout_2.addWidget(self.types_label)
        self.horizontalLayout.addLayout(self.verticalLayout_2)
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")


        self.Ip_address_lineEdit = QtWidgets.QLineEdit(self.widget)
        #validate an ip address
        ipRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"
        # Regulare expression
        ipRegex = QRegExp("^" + ipRange + "\\." + ipRange + "\\." + ipRange + "\\." + ipRange + "$")
        ipValidator = QRegExpValidator(ipRegex, self.Ip_address_lineEdit)
        self.Ip_address_lineEdit.setEnabled(True)
        self.Ip_address_lineEdit.setValidator(ipValidator)




        self.Ip_address_lineEdit.setObjectName("Ip_address_lineEdit")
        self.verticalLayout.addWidget(self.Ip_address_lineEdit)
        self.ports_lineEdit = QtWidgets.QLineEdit(self.widget)
        self.ports_lineEdit.setObjectName("ports_lineEdit")
        self.verticalLayout.addWidget(self.ports_lineEdit)
        self.types_comboBox = QtWidgets.QComboBox(self.widget)
        self.types_comboBox.setObjectName("types_comboBox")
        self.types_comboBox.addItem("")
        self.types_comboBox.addItem("")
        self.types_comboBox.addItem("")
        self.types_comboBox.addItem("")
        self.verticalLayout.addWidget(self.types_comboBox)
        self.horizontalLayout.addLayout(self.verticalLayout)
        self.verticalLayout_3.addLayout(self.horizontalLayout)
        self.buttonBox = QtWidgets.QDialogButtonBox(self.widget)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout_3.addWidget(self.buttonBox)

        self.retranslateUi(Dialog)
        self.buttonBox.accepted.connect(self.singlePing)
        #add the following line in to accept the user clicking ok and then closing down the dialog. you can accept.connect multiple times
        self.buttonBox.accepted.connect(Dialog.accept)

        self.buttonBox.rejected.connect(Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def singlePing(self):
        print('the ip address you will ping is: ' + self.Ip_address_lineEdit.text())
        response = os.popen('ping ' + self.Ip_address_lineEdit.text())
        for line in response.readlines():
            print(line)

    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.groupBox.setTitle(_translate("Dialog", "Scanner"))
        self.ip_label.setText(_translate("Dialog", "Target_IP"))
        self.ports_label.setText(_translate("Dialog", "Commands"))
        self.types_label.setText(_translate("Dialog", "Types"))
        self.types_comboBox.setItemText(0, _translate("Dialog", "ping"))
        #self.types_comboBox.setItemText(1, _translate("Dialog", "ping sweep"))
        #self.types_comboBox.setItemText(2, _translate("Dialog", "tcp connect"))
        #self.types_comboBox.setItemText(3, _translate("Dialog", "service scan"))



if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Scanner_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())

下面是我尝试执行代码的尝试,我需要帮助来修复

ScannerDialog.py


import os
import asyncio
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtNetwork import QHostAddress
from PyQt5.QtCore import QRegExp, QThread, pyqtSignal
from PyQt5.QtGui import QRegExpValidator


class RunThread(QThread):
    ping_value = pyqtSignal()

    def __init__(self, parent=None):
        super(RunThread, self).__init__(parent)
        self.ping = ping_start
        self.is_running = True

    def run(self):
        print('the ip address you will ping is: ' + Scanner_Dialog.Ip_address_lineEdit.text())
        response = os.popen('ping '+ Scanner_Dialog.Ip_address_lineEdit.text())
        for line in response.readlines():
            #self.sleep(0.1)
            print(line)


    def stop(self):
        self.is_running = False
        print('stopping thread...')
        self.terminate()

class Scanner_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(254, 176)
        self.groupBox = QtWidgets.QGroupBox(Dialog)
        self.groupBox.setGeometry(QtCore.QRect(10, 10, 231, 151))
        self.groupBox.setObjectName("groupBox")
        self.widget = QtWidgets.QWidget(self.groupBox)
        self.widget.setGeometry(QtCore.QRect(20, 30, 199, 107))
        self.widget.setObjectName("widget")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.widget)
        self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.ip_label = QtWidgets.QLabel(self.widget)
        self.ip_label.setObjectName("ip_label")
        self.verticalLayout_2.addWidget(self.ip_label)
        self.ports_label = QtWidgets.QLabel(self.widget)
        self.ports_label.setObjectName("ports_label")
        self.verticalLayout_2.addWidget(self.ports_label)
        self.types_label = QtWidgets.QLabel(self.widget)
        self.types_label.setObjectName("types_label")
        self.verticalLayout_2.addWidget(self.types_label)
        self.horizontalLayout.addLayout(self.verticalLayout_2)
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setObjectName("verticalLayout")


        self.Ip_address_lineEdit = QtWidgets.QLineEdit(self.widget)
        #validate an ip address
        ipRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"
        # Regulare expression
        ipRegex = QRegExp("^" + ipRange + "\\." + ipRange + "\\." + ipRange + "\\." + ipRange + "$")
        ipValidator = QRegExpValidator(ipRegex, self.Ip_address_lineEdit)
        self.Ip_address_lineEdit.setEnabled(True)
        self.Ip_address_lineEdit.setValidator(ipValidator)


        self.verticalLayout.addWidget(self.Ip_address_lineEdit)
        self.ports_lineEdit = QtWidgets.QLineEdit(self.widget)
        self.ports_lineEdit.setObjectName("ports_lineEdit")
        self.verticalLayout.addWidget(self.ports_lineEdit)
        self.types_comboBox = QtWidgets.QComboBox(self.widget)
        self.types_comboBox.setObjectName("types_comboBox")
        self.types_comboBox.addItem("")
        self.types_comboBox.addItem("")
        self.types_comboBox.addItem("")
        self.types_comboBox.addItem("")
        self.verticalLayout.addWidget(self.types_comboBox)
        self.horizontalLayout.addLayout(self.verticalLayout)
        self.verticalLayout_3.addLayout(self.horizontalLayout)
        self.buttonBox = QtWidgets.QDialogButtonBox(self.widget)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout_3.addWidget(self.buttonBox)

        self.retranslateUi(Dialog)
        self.buttonBox.accepted.connect(RunThread)
        #add the following line in to accept the user clicking ok and then closing down the dialog. you can accept.connect multiple times
        #self.buttonBox.accepted.connect(Dialog.accept)

        self.buttonBox.rejected.connect(Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)





    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.groupBox.setTitle(_translate("Dialog", "Scanner"))
        self.ip_label.setText(_translate("Dialog", "Target_IP"))
        self.ports_label.setText(_translate("Dialog", "Commands"))
        self.types_label.setText(_translate("Dialog", "Types"))
        self.types_comboBox.setItemText(0, _translate("Dialog", "ping"))
        #self.types_comboBox.setItemText(1, _translate("Dialog", "ping sweep"))
        #self.types_comboBox.setItemText(2, _translate("Dialog", "tcp connect"))
        #self.types_comboBox.setItemText(3, _translate("Dialog", "service scan"))



if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Dialog = QtWidgets.QDialog()
    ui = Scanner_Dialog()
    ui.setupUi(Dialog)
    Dialog.show()
    sys.exit(app.exec_())



用户应输入目标IP地址,然后单击确定>,然后对话框将关闭,并且ping程序应ping一个IP地址。

0 个答案:

没有答案