D
D
Dmitry Fellow2020-11-29 23:46:55
Multithreading
Dmitry Fellow, 2020-11-29 23:46:55

How to properly set up threads in code using PyQt?

I just can't get multithreading connected to one of my functions in the program. The program just doesn't respond to pressing the button. I tried to change the value of "change_value" to the value of the variable "lineEdit_2" - the same result. What is my mistake?

import urllib.request
import time
import json
import socket
import requests, sys
import ipaddress

from urllib.request import Request, urlopen
import os
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMessageBox, QLineEdit
from PyQt5.QtCore import QThread,pyqtSignal

#Сигнал
class mythread(QThread):
    change_value = pyqtSignal(int)


claw)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(2)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def showMessageBox(self,title,messege):
        msgBox = QtGui.QMessegeBox()
        msgBox.setIcon(QtGui.QMessegeBox.Warning)
        msgBox.setWindowTitle(title)
        msgBox.setText(messege)
        msgBox.setStandardButtons(QtGui.QMessageBox.Ok)
        msgBox.exce_()


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "Punch!"))
        self.label.setText(_translate("MainWindow", "               IP"))
        self.label_2.setText(_translate("MainWindow", "                                                              Work place"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Whois Function"))
        self.pushButton_3.setText(_translate("MainWindow", "Punch!"))
        self.label_5.setText(_translate("MainWindow", "               IP"))
        self.label_6.setText(_translate("MainWindow", "                                                              Work place"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Port Scanner "))
        self.label_3.setText(_translate("MainWindow", "               IP"))
        self.label_4.setText(_translate("MainWindow", "                                                              Work place"))
        self.pushButton_2.setText(_translate("MainWindow", "Punch!"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Blacklists checkout "))

     
    ## Ниже функция
    def run(self):
            mas = [20, 21, 22, 23, 25, 42, 43, 53, 67, 69, 80, 110, 115, 123, 137, 138, 139, 143, 161, 179, 443, 445,
                   514, 515,
                   993, 995]
            host = self.lineEdit_2.text()
            try:
                ipaddress.ip_network(host)
                for port in mas:
                    s = socket.socket()
                    s.settimeout(1)
                    try:
                        s.connect((host, port))
                        time.sleep(1.5)
                        per2 = (str(port) + ' port open!')

                        self.textEdit_5.setText(per2)
                        print(per2)
                    except socket.error:
                        per3 = (str(port) + ' port locked!')
                        self.textEdit_5.append(per3)
            except ValueError:
                QMessageBox.warning(self, 'Error!', 'Invalid IP!')

class Window(QtWidgets.QMainWindow, Ui_MainWindow):
        def __init__(self):
            super(Window, self).__init__()
            self.setupUi(self)
          #  self.pushButton_2.clicked.connect(self.list)
           # self.pushButton.clicked.connect(self.whois)
            self.pushButton_3.clicked.connect(self.run)

        #Подключение к потоку
        def stp(self):
            self.thread = mythread()
            self.self.change_value.connect(self.run)
            self.thread.start()






if __name__ == '__main__':
             import sys
             app = QtWidgets.QApplication(sys.argv)
             app.setStyle('Fusion')
             w = Window()  
             w.show()  
             sys.exit(app.exec_())

Answer the question

In order to leave comments, you need to log in

2 answer(s)
Z
ZIK1337, 2020-11-30
@ZIK1337

self.pushButton_3.clicked.connect(self.run)
On
self.pushButton_3.clicked.connect(self.stp)
T.e. to the function where the thread starts

B
bbkmzzzz, 2020-11-30
@bbkmzzzz

In this form, as given here, it will not work at all, in this form it will not even start.
̶Q̶t̶h̶r̶e̶a̶d̶ ̶n̶ ̶n̶a̶s̶l̶d̶d̶n̶k̶ ̶q̶o̶b̶j̶c̶t̶ ̶i̶ ̶n̶ ̶m̶ ̶e̶t̶ ̶i̶s̶p̶c̶ ̶ ̶s̶y̶n̶a̶l̶l̶ -> UPD: since a certain version (in 5.15 for sure) QThread has finally become a successor to QObject, so that it can now emit signals itself. The crutch from the signaller class is no longer relevant.
You cannot call changes to window widgets from an adjacent thread, only by emitting and catching signals.
Do not inherit from two classes at the same time, you will get weird.
The toaster has examples of how to link Qt in a simple way.
In general, through QRunnable, it looks like this:

import sys
import time

from PySide2.QtCore import QThreadPool, QRunnable, Signal, QObject
from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton, QWidget, QHBoxLayout


class Main(QMainWindow):
    def __init__(self):
        super(Main, self).__init__()
        centralWidget = QWidget(self)
        self.setCentralWidget(centralWidget)

        # добавляем компонощик
        self.h_grid = QHBoxLayout(centralWidget)

        self.thread = QThreadPool().globalInstance()
        # добаляем кнопки
        self.button = QPushButton('Start thread')
        self.h_grid.addWidget(self.button)

        self.worker = Worker()
        self.worker.finished.connect(self.__on_finish)

        self.button.clicked.connect(self.start_worker)

    def start_worker(self):
        self.thread.start(self.worker)

    def __on_finish(self):
        print('Воркер закончил работу')


class WorkerSignaller(QObject):
    finished = Signal()


class Worker(QRunnable):
    def __init__(self):
        super(Worker, self).__init__()
        self.signaller = WorkerSignaller()
        self.finished = self.signaller.finished

    def run(self):
        print(f'Я воркер, и я запускаюсь')
        time_to_sleep = 10
        print(f'Я воркер, и я сплю {time_to_sleep} секунд')
        time.sleep(time_to_sleep)
        print(f'Я воркер, и я поспал')
        self.finished.emit()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Main()
    ex.show()
    sys.exit(app.exec_())

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question