Answer the question
In order to leave comments, you need to log in
What to change so that the interface is not blocked?
I wrote a small program that creates an additional thread in which the ping command is executed, after which the data is displayed on the screen. I can not understand why the interface is blocked, although the similar console code on python\threading is not blocked. Tell me what's wrong in the code? I assume that I used signals\slots incorrectly.
About the code:
create a Worker(QThread) class
add a runping signal
in the main class
pingFromOS(ip) method creates a ping process and returns the result
OnPing() method -- called on the thread via runping.connect()
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from subprocess import Popen,PIPE
import sys
lock = QReadWriteLock()
class Worker(QThread):
runping = pyqtSignal()
def __init__(self,parent = None ):
QThread.__init__(self,parent)
def run(self):
self.runping.emit()
class MainWindow(QMainWindow):
def __init__(self,*args,**kwargs):
super(MainWindow,self).__init__(*args,**kwargs)
self.initUI()
def initUI(self):
self.width = 600
self.height = 600
self.resize(self.width,self.height)
self.center()
self.ipField = QLineEdit(self)
self.ipField.setText('127.1.1.0')
self.ipField.setGeometry(10,10,100,25)
self.button = QPushButton("ping",self)
self.button.setGeometry(120,10,100,25)
self.button.clicked.connect(self.onPressPing)
self.console = QPlainTextEdit(self)
self.console.setGeometry(5,50,self.width-10,self.height-60)
self.setWindowTitle('Ping from os')
self.w = Worker()
self.w.runping.connect(self.OnPing)
self.show()
def onPressPing(self):
self.w.run()
def OnPing(self):
lock.lockForWrite()
ip = self.ipField.text()
lock.unlock()
res = self.pingFromOS('localhost')
lock.lockForWrite()
self.console.appendPlainText(res)
lock.unlock()
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def pingFromOS(self,ip):
if ip is None:
return b"ip is None"
if ip=='':
return b'ip is empty'
pcArg=['ping','-c','9',ip]
proc = Popen(pcArg,stdout=PIPE)
out = proc.stdout.readlines()
res = b""
for row in out:
res+=row
proc.stdout.close()
return res.decode()
if __name__ == '__main__':
# Next, create an application object.
QApplication.setDesktopSettingsAware(False)
app = QApplication(sys.argv)
# Show it.
frame = MainWindow()
# Start the event loop.
sys.exit(app.exec_())
Answer the question
In order to leave comments, you need to log in
I rewrote the code, now it works, the code is just an example. Locks and queues are not implemented.
Signals slots official. documentation
Example on github
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from subprocess import Popen,PIPE
import sys
lock = QReadWriteLock()
class Worker(QThread):
finished = pyqtSignal(str)
def __init__(self,parent = None ):
super(Worker,self).__init__(parent)
def setIP(self,ip):
self.ip = ip
def pingFromOS(self,ip):
if ip is None:
return b"ip is None"
if ip=='':
return b'ip is empty'
pcArg=['ping','-c','9',ip]
proc = Popen(pcArg,stdout=PIPE)
out = proc.stdout.readlines()
res = b""
for row in out:
res+=row
proc.stdout.close()
return res.decode()
def run(self):
res = self.pingFromOS(self.ip)
self.finished.emit(res)
class MainWindow(QMainWindow):
def __init__(self,*args,**kwargs):
super(MainWindow,self).__init__(*args,**kwargs)
self.initUI()
def initUI(self):
self.width = 600
self.height = 600
self.resize(self.width,self.height)
self.center()
self.ipField = QLineEdit(self)
self.ipField.setText('127.1.1.0')
self.ipField.setGeometry(10,10,100,25)
self.button = QPushButton("ping",self)
self.button.setGeometry(120,10,100,25)
self.button.clicked.connect(self.onPressPing)
self.console = QPlainTextEdit(self)
self.console.setGeometry(5,50,self.width-10,self.height-60)
self.setWindowTitle('Ping from os')
self.show()
def onPressPing(self):
self.w = Worker()
self.w.setIP(self.ipField.text())
self.w.start()
self.w.finished.connect(self.OnPing)
def OnPing(self,res):
self.console.appendPlainText(res)
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
if __name__ == '__main__':
# Next, create an application object.
QApplication.setDesktopSettingsAware(False)
app = QApplication(sys.argv)
# Show it.
frame = MainWindow()
# Start the event loop.
sys.exit(app.exec_())
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question