Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pyqt Gui Freezes while in loop

Tags:

python

pyqt

pyqt4

Im making port scanner program with PyQt but Gui freezes when i activate loop.How can i fix that? I added time.sleep() function but it still freezes. This is the function it freezes. Thanks.

        try:
            time.sleep(1) 
            hostname=self.adres.text()
            hostip=socket.gethostbyname(hostname)
            uyari1="Scanning remote host, {}\n".format(hostip)
            self.durum.append(uyari1)
            print(uyari1)
            for port in range(1,1025):
                time.sleep(0.1)  
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                result = sock.connect_ex((hostip, port))
                if result == 0:
                    time.sleep(0.01) 
                    print ("Port {}: \t Open".format(port))
                    self.durum.append("Port {}: \t Open\n".format(port))
                sock.close()

Full code:

import socket,os,time
from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(596, 412)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.label = QtGui.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(120, -10, 331, 91))
        self.label.setObjectName(_fromUtf8("label"))
        self.label_2 = QtGui.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(10, 90, 91, 16))
        self.label_2.setObjectName(_fromUtf8("label_2"))
        self.adres = QtGui.QLineEdit(self.centralwidget)
        self.adres.setGeometry(QtCore.QRect(100, 90, 371, 22))
        self.adres.setObjectName(_fromUtf8("adres"))
        self.durum = QtGui.QTextEdit(self.centralwidget)
        self.durum.setGeometry(QtCore.QRect(10, 140, 571, 191))
        self.durum.setObjectName(_fromUtf8("durum"))
        self.baslat = QtGui.QPushButton(self.centralwidget)
        self.baslat.setGeometry(QtCore.QRect(480, 90, 101, 21))
        self.baslat.setObjectName(_fromUtf8("baslat"))
        self.dosyaya = QtGui.QPushButton(self.centralwidget)
        self.dosyaya.setGeometry(QtCore.QRect(490, 340, 91, 25))
        self.dosyaya.setObjectName(_fromUtf8("dosyaya"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 596, 21))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.hakkindaa = QtGui.QPushButton(self.centralwidget)
        self.hakkindaa.setGeometry(QtCore.QRect(10, 340, 91, 25))
        self.hakkindaa.setObjectName(_fromUtf8("hakkindaa"))
        self.hakkindaa.setText("Hakkında")
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)
        QtCore.QObject.connect(self.hakkindaa, QtCore.SIGNAL(_fromUtf8("clicked()")), self.hakkinda)
        QtCore.QObject.connect(self.dosyaya, QtCore.SIGNAL(_fromUtf8("clicked()")), self.dosyayaya)
        QtCore.QObject.connect(self.baslat, QtCore.SIGNAL(_fromUtf8("clicked()")), self.baslat_btn)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def hakkinda(self):
        QtGui.QMessageBox.about(None, "About", "Ege Öz 2014")

    def baslat_btn(self):
        try:
            time.sleep(1) 
            hostname=self.adres.text()
            hostip=socket.gethostbyname(hostname)
            uyari1="Scanning remote host, {}\n".format(hostip)
            self.durum.append(uyari1)
            print(uyari1)
            for port in range(1,1025):
                time.sleep(0.1)  
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                result = sock.connect_ex((hostip, port))
                if result == 0:
                    time.sleep(0.01) 
                    print ("Port {}: \t Open".format(port))
                    self.durum.append("Port {}: \t Open\n".format(port))
                sock.close()

        except socket.gaierror:
            self.durum.append("Hostname could not be resolved.")
            print("Hostname could not be resolved.")
            self.adres.setText("")
        except socket.error:

            self.durum.append("Could not connect to server.")
            print("Could not connect to server.")
            self.adres.setText("")
    def dosyayaya(self):
            self.durum.append("Saving log file to home directory...")
            ev=os.getenv("USER")
            data=self.durum.toPlainText()
            yol="/home/"+ev+"/portscanner.log"
            f = open (yol,"w")
            f.write(data)
            f.close()
            self.durum.append("Log file saved.")
            print ("Log file saved.")
    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "Port Scanner", None))
        self.label.setText(_translate("MainWindow", "<html><head/><body><p align=\"center\"><span style=\" font-size:11pt; font-weight:600;\">Port Scanner</span></p><p>Enter the remote host adress and press start.</p></body></html>", None))
        self.label_2.setText(_translate("MainWindow", "Remote Host:", None))
        self.baslat.setText(_translate("MainWindow", "Start Scanning", None))
        self.dosyaya.setText(_translate("MainWindow", "Save to file", None))    

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
like image 504
user3755771 Avatar asked Feb 18 '26 13:02

user3755771


2 Answers

You should call QtCore.QCoreApplication.processEvents() within your for loop to make the Qt's event loop proceed the incoming event (from keyboard or mouse).

like image 66
Antoine Avatar answered Feb 20 '26 02:02

Antoine


Although calling QtCore.QCoreApplication.processEvents() works now, I have read in many places on the web that it should be a last resort. Unfortunately none of the sources clearly explain why -- but see for example

  • How to make Qt work when main thread is busy?
  • Should I use QCoreApplication::processEvents() or QApplication::processEvents()?
  • How to implement a QThread that runs forever{} with a QWaitCondition but still needs to catch another Slot while doing that
  • http://qt-project.org/forums/viewthread/22967

So it does seem allowed, but in general, it seems to be better design to use QTimer or QThread.

like image 23
Oliver Avatar answered Feb 20 '26 03:02

Oliver



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!