使用 QThread 两次单击按钮 2 后 Pyqt GUI 突然没有响应
Posted
技术标签:
【中文标题】使用 QThread 两次单击按钮 2 后 Pyqt GUI 突然没有响应【英文标题】:Pyqt GUI suddenly not responding after clicked button 2 twice using QThread 【发布时间】:2017-06-14 03:59:49 【问题描述】:我尝试为我的进程创建 QThread
类,当我点击 Generate 按钮时,我的 QTextEdit
中没有显示任何内容,当我再次点击该按钮时,我的 GUI 突然 没有响应。
我的代码
更新代码
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import ipaddress
class Stream(QObject):
newText = pyqtSignal(str)
def write(self, text):
self.newText.emit(str(text))
def flush(self):
pass
class MyClass(object):
def __init__(self, device_type=None, ip=None, username=None, password=None, secret=None, command=None):
self.device_type = device_type
self.ip = ip
self.username = username
self.password = password
self.secret = secret
self.command = command
class sshConnection(QThread):
def __init__(self):
QThread.__init__(self)
def __del__(self):
self.wait()
def runSSH(self):
#doo process
print('Haii')
for x in range(100):
print(x)
class Widget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
self.device_list = [] # object array
self.setWindowTitle("Network Automation")
self.setFixedSize(350,500)
############################# Input IP
sys.stdout = Stream(newText=self.onUpdateText)
# Device Type
lb_device_list = QLabel(self)
lb_device_list.setText('Device Type')
self.cb_device_list = QComboBox(self)
self.cb_device_list.addItem('cisco_ios')
self.cb_device_list.addItem('cisco_s300')
# Ip Device
lb_ip = QLabel(self)
lb_ip.setText('IP Address')
self.le_ip = QLineEdit(self)
self.le_ip.setText('')
self.le_ip.setPlaceholderText('Input Device IP')
self.le_ip.setFixedWidth(150)
# username
lb_username = QLabel(self)
self.le_username = QLineEdit(self)
lb_username.setText('Username')
self.le_username.setText('')
self.le_username.setPlaceholderText('Input Username')
self.le_username.setFixedWidth(150)
# password
lb_password = QLabel(self)
self.le_password = QLineEdit(self)
lb_password.setText('Password')
self.le_password.setText('')
self.le_password.setPlaceholderText('Input Password')
self.le_password.setFixedWidth(150)
# Privilage Password
lb_enable = QLabel(self)
lb_enable.setText('Privilege Mode Password')
self.le_enable = QLineEdit(self)
self.le_enable.setText('')
self.le_enable.setPlaceholderText('Input Enable Password')
self.le_enable.setFixedWidth(150)
# button generate and add
btgenerate = QPushButton(self)
btgenerate.setText('Generate')
btgenerate.setFixedWidth(70)
btadd = QPushButton(self)
btadd.setText('Add')
# button delete
btdel = QPushButton(self)
btdel.setFixedWidth(70)
btdel.setText('Remove')
# line
line = QFrame(self)
line.setFrameShape(QFrame.VLine)
line.setFrameShadow(QFrame.Sunken)
line.setLineWidth(3)
#line 2
line2 = QFrame(self)
line2.setFrameShape(QFrame.HLine)
line2.setFrameShadow(QFrame.Sunken)
line2.setLineWidth(3)
########################### Layout Ip Device List
lb3 = QLabel(self)
lb3.setText('IP Device List')
self.ip_device_list = QListWidget(self)
self.ip_device_list.setFixedWidth(150)
# self.combobox_ip_list = QComboBox(self)
# self.combobox_ip_list.setFixedWidth(170)
############################## SubLayout and Layout
hblayout = QHBoxLayout()
hblayout.addWidget(btgenerate)
hblayout.addWidget(btadd)
############################### Processs
processlabel = QLabel("Process",self)
self.process = QTextEdit(self)
self.process.setLineWrapColumnOrWidth(400)
self.process.setLineWrapMode(QTextEdit.FixedPixelWidth)
self.process.setReadOnly(True)
sublayout = QVBoxLayout()
sublayout.addWidget(lb_device_list)
sublayout.addWidget(self.cb_device_list)
sublayout.addWidget(lb_ip)
sublayout.addWidget(self.le_ip)
sublayout.addWidget(lb_username)
sublayout.addWidget(self.le_username)
sublayout.addWidget(lb_password)
sublayout.addWidget(self.le_password)
sublayout.addWidget(lb_enable)
sublayout.addWidget(self.le_enable)
sublayout.addLayout(hblayout)
sublayout2 = QVBoxLayout()
sublayout2.addWidget(lb3)
sublayout2.addWidget(self.ip_device_list)
#sublayout2.addWidget(self.combobox_ip_list)
sublayout2.addWidget(btdel)
sublayout2.addStretch(1)
sublayout3 = QVBoxLayout()
sublayout3.addWidget(processlabel)
sublayout3.addWidget(self.process)
layout = QGridLayout(self)
layout.addLayout(sublayout, 0, 0)
layout.addWidget(line, 0, 1)
layout.addWidget(line2, 1, 0, 1, 3)
#layout.addWidget(processlabel,2,0)
layout.addLayout(sublayout3,2,0,2,3)
layout.addLayout(sublayout2, 0, 2)
btadd.clicked.connect(self.addDevice)
btdel.clicked.connect(self.remove)
btgenerate.clicked.connect(self.runThread)
def onUpdateText(self, text):
cursor = self.process.textCursor()
cursor.movePosition(QTextCursor.End)
cursor.insertText(text)
self.process.setTextCursor(cursor)
self.process.ensureCursorVisible()
# ----------- AddDevice Process
def addDevice(self):
try:
ip = self.le_ip.text()
ipaddress.ip_address(ip)
device_type = str(self.cb_device_list.currentText())
username = self.le_username.text()
password = self.le_password.text()
secret = self.le_enable.text()
command = 'show tech'
coomand2 = ''
self.device_list.append(MyClass(device_type, ip, username, password, secret, command))
# self.combobox_ip_list.addItem(ip)# Add Ip to ComboBox
self.ip_device_list.addItem(ip)
self.le_ip.clear()
self.le_username.clear()
self.le_password.clear()
self.le_enable.clear()
for list in self.device_list:
print(list.ip, list.device_type)
except ValueError:
print("insert you're ip correctly")
QMessageBox.question(self, 'Warning', "Insert You're IP Corecctly")
def remove(self):
index = self.ip_device_list.currentRow()
if index != -1:
self.ip_device_list.takeItem(index)
del self.device_list[index]
def runThread(self):
self.run_thread = sshConnection()
self.run_thread.finished.connect(app.exit)
self.run_thread.start()
app = QApplication(sys.argv)
app.setStyle('cleanlooks')
window = Widget()
window.show()
sys.exit(app.exec_())
【问题讨论】:
【参考方案1】:QThread
期望你实现run
方法,我认为它与runSSH
相同,但事实并非如此,你可以做的是在 run 方法中调用它,在我下面展示的测试中我删除了self.run_thread.finished.connect(app.exit)
这一行,因为它会在打印作业用不了多长时间后立即关闭。
class sshConnection(QThread):
def __init__(self):
QThread.__init__(self)
def __del__(self):
self.wait()
def run(self):
self.runSSH()
def runSSH(self):
#doo process
print('Haii')
for x in range(100):
print(x)
【讨论】:
它的工作.. 所以我需要创建run
方法来调用runSSH
,如果我不创建run
方法runSSH
不起作用?
没错,run方法是必须实现的虚方法。
sorryy.. 如果出现错误,我该如何停止线程?我尝试使用self.exec_()
,但它不起作用
阅读:***.com/questions/23923354/…以上是关于使用 QThread 两次单击按钮 2 后 Pyqt GUI 突然没有响应的主要内容,如果未能解决你的问题,请参考以下文章