更改字典中的数据后功能停止工作 Python/PyQt5
Feature stopped working after changing data in the dictionary Python/PyQt5
我已经用我的这个小程序解决了所有问题,但是在我将我将要使用的实际数据插入字典后,button.setEnable(False) 停止工作。有什么想法吗?
代码:
self.countBtn = QPushButton("Do something", self)
self.countBtn.clicked.connect(self.onButtonClick)
def onButtonClick(self):
self.serversChecked = Worker()
self.textOutput.clear()
self.serversChecked.amount_of_servers.connect(self.setupUi)
self.serversChecked.progress.connect(self.countCheckedServers)
self.serversChecked.offline_servers.connect(self.toScreen)
self.serversChecked.pbar_step.connect(self.pbar_step)
self.serversChecked.amount_of_servers.connect(self.maxPbar)
self.serversChecked.start()
self.countBtn.setEnabled(False)
self.serversChecked.finished.connect(
lambda: self.countBtn.setEnabled(True)
)
这是我认为相关的所有代码,如果需要更多,我可以提供。
欢迎任何想法,因为我很困惑...
编辑:根据要求,其余代码:
import sys, os, subprocess
from PyQt5.QtCore import QThread, pyqtSignal, Qt
from PyQt5.QtWidgets import (
QApplication,
QLabel,
QMainWindow,
QPlainTextEdit,
QPushButton,
QVBoxLayout,
QWidget,
QProgressBar
)
class Worker(QThread):
finished = pyqtSignal(str)
progress = pyqtSignal(int)
offline_servers = pyqtSignal(str)
amount_of_servers = pyqtSignal(int)
pbar_step = pyqtSignal(float)
start_long_task = pyqtSignal(int)
ips = {
'001' : '142.250.178.14', '002' : '104.18.2.89', '003' : '10.251.63.23'
}
amount_of_servers_int = len(ips)
def run(self):
self.start_long_task.emit(1)
amount_of_servers_int = len(self.ips)
self.amount_of_servers.emit(amount_of_servers_int)
with open(os.devnull, 'w') as DEVNULL:
server = 0
pbar_progress = 0
for x, y in self.ips.items():
try:
subprocess.check_call(
['ping', '-n', '1', y],
stdout=DEVNULL, # suppress output
stderr=DEVNULL
)
except subprocess.CalledProcessError:
nextServer = (working output here)
self.offline_servers.emit(nextServer)
server = server + 1
pbar_progress = pbar_progress + 1
self.pbar_step.emit(pbar_progress)
self.progress.emit(server)
self.finished.emit('')
class Window(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi()
def setupUi(self):
self.setWindowTitle("")
self.resize(300, 400)
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.textOutput = QPlainTextEdit(self)
self.textOutput.setReadOnly(True)
self.textOutput.resize(280, 300)
self.textOutput.move(10, 5)
self.serversCheckedtoScreen = QLabel("Checked: ", self)
self.serversCheckedtoScreen.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
self.pbar = QProgressBar(self, objectName="progressBar")
self.pbar.setGeometry(200, 80, 280, 20)
self.pbar.setValue(0)
self.pbar.setMinimum(0)
self.countBtn = QPushButton("Check Servers", self)
self.countBtn.clicked.connect(self.onButtonClick)
# Set the layout
layout = QVBoxLayout()
layout.addWidget(self.textOutput)
layout.addWidget(self.serversCheckedtoScreen)
layout.addWidget(self.pbar)
layout.addWidget(self.countBtn)
self.pbar.setStyleSheet("""
QWidget {
text-align: center;
}
""")
self.centralWidget.setLayout(layout)
def onButtonClick(self):
self.serversChecked = Worker()
self.textOutput.clear()
################This is the issue as pointed out by @musicamante ##########
**self.serversChecked.amount_of_servers.connect(self.setupUi)**
################This piece of code shouldnt even be here, code blindness is a thing #####
self.serversChecked.progress.connect(self.countCheckedServers)
self.serversChecked.offline_servers.connect(self.toScreen)
self.serversChecked.pbar_step.connect(self.pbar_step)
self.serversChecked.amount_of_servers.connect(self.maxPbar)
self.serversChecked.start_long_task.connect(self.disableButton)
self.serversChecked.start()
self.countBtn.setEnabled(False) ##### WHY IT DOESNT WORK
self.serversChecked.finished.connect(
lambda: self.countBtn.setEnabled(True)
)
def countCheckedServers(self, value):
max = self.serversChecked.amount_of_servers_int
self.serversCheckedtoScreen.setText(f"Servers Checked: {value} / " + str(max))
def toScreen(self, value):
self.textOutput.appendPlainText(value)
def pbar_step(self, value):
self.pbar.setValue(int(value))
def maxPbar(self,value):
self.pbar.setMaximum(value)
def disableButton(self, n): # added extra function to check but makes no difference
if n == 1:
self.countBtn.setDisabled(True)
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec())
正如@musicamante 在评论中正确指出的那样,我在
下留下了一行代码
def onButtonClick(self):
self.serversChecked = Worker()
self.textOutput.clear()
移除后
self.serversChecked.amount_of_servers.connect(self.setupUi)
按照他的建议问题已经解决了。我已经要求他创建一个 asnwer,这样我就可以信任他,我希望他能尽快这样做。因此,我还没有标记为完成。
同时复制他的原始评论:
You're calling self.setupUi
everytime the worker is started, so you're creating a new UI. That signal is not emitted instantly, but asynchronously. So, the button is disabled, but right after that the thread is actually started, which creates a new UI, with an enabled button. Remove self.serversChecked.amount_of_servers.connect(self.setupUi)
.
可悲的是,代码盲目是一回事,但是,有一些杰出的人愿意提供帮助。再次感谢@musicamante
我已经用我的这个小程序解决了所有问题,但是在我将我将要使用的实际数据插入字典后,button.setEnable(False) 停止工作。有什么想法吗?
代码:
self.countBtn = QPushButton("Do something", self)
self.countBtn.clicked.connect(self.onButtonClick)
def onButtonClick(self):
self.serversChecked = Worker()
self.textOutput.clear()
self.serversChecked.amount_of_servers.connect(self.setupUi)
self.serversChecked.progress.connect(self.countCheckedServers)
self.serversChecked.offline_servers.connect(self.toScreen)
self.serversChecked.pbar_step.connect(self.pbar_step)
self.serversChecked.amount_of_servers.connect(self.maxPbar)
self.serversChecked.start()
self.countBtn.setEnabled(False)
self.serversChecked.finished.connect(
lambda: self.countBtn.setEnabled(True)
)
这是我认为相关的所有代码,如果需要更多,我可以提供。
欢迎任何想法,因为我很困惑...
编辑:根据要求,其余代码:
import sys, os, subprocess
from PyQt5.QtCore import QThread, pyqtSignal, Qt
from PyQt5.QtWidgets import (
QApplication,
QLabel,
QMainWindow,
QPlainTextEdit,
QPushButton,
QVBoxLayout,
QWidget,
QProgressBar
)
class Worker(QThread):
finished = pyqtSignal(str)
progress = pyqtSignal(int)
offline_servers = pyqtSignal(str)
amount_of_servers = pyqtSignal(int)
pbar_step = pyqtSignal(float)
start_long_task = pyqtSignal(int)
ips = {
'001' : '142.250.178.14', '002' : '104.18.2.89', '003' : '10.251.63.23'
}
amount_of_servers_int = len(ips)
def run(self):
self.start_long_task.emit(1)
amount_of_servers_int = len(self.ips)
self.amount_of_servers.emit(amount_of_servers_int)
with open(os.devnull, 'w') as DEVNULL:
server = 0
pbar_progress = 0
for x, y in self.ips.items():
try:
subprocess.check_call(
['ping', '-n', '1', y],
stdout=DEVNULL, # suppress output
stderr=DEVNULL
)
except subprocess.CalledProcessError:
nextServer = (working output here)
self.offline_servers.emit(nextServer)
server = server + 1
pbar_progress = pbar_progress + 1
self.pbar_step.emit(pbar_progress)
self.progress.emit(server)
self.finished.emit('')
class Window(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi()
def setupUi(self):
self.setWindowTitle("")
self.resize(300, 400)
self.centralWidget = QWidget()
self.setCentralWidget(self.centralWidget)
self.textOutput = QPlainTextEdit(self)
self.textOutput.setReadOnly(True)
self.textOutput.resize(280, 300)
self.textOutput.move(10, 5)
self.serversCheckedtoScreen = QLabel("Checked: ", self)
self.serversCheckedtoScreen.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
self.pbar = QProgressBar(self, objectName="progressBar")
self.pbar.setGeometry(200, 80, 280, 20)
self.pbar.setValue(0)
self.pbar.setMinimum(0)
self.countBtn = QPushButton("Check Servers", self)
self.countBtn.clicked.connect(self.onButtonClick)
# Set the layout
layout = QVBoxLayout()
layout.addWidget(self.textOutput)
layout.addWidget(self.serversCheckedtoScreen)
layout.addWidget(self.pbar)
layout.addWidget(self.countBtn)
self.pbar.setStyleSheet("""
QWidget {
text-align: center;
}
""")
self.centralWidget.setLayout(layout)
def onButtonClick(self):
self.serversChecked = Worker()
self.textOutput.clear()
################This is the issue as pointed out by @musicamante ##########
**self.serversChecked.amount_of_servers.connect(self.setupUi)**
################This piece of code shouldnt even be here, code blindness is a thing #####
self.serversChecked.progress.connect(self.countCheckedServers)
self.serversChecked.offline_servers.connect(self.toScreen)
self.serversChecked.pbar_step.connect(self.pbar_step)
self.serversChecked.amount_of_servers.connect(self.maxPbar)
self.serversChecked.start_long_task.connect(self.disableButton)
self.serversChecked.start()
self.countBtn.setEnabled(False) ##### WHY IT DOESNT WORK
self.serversChecked.finished.connect(
lambda: self.countBtn.setEnabled(True)
)
def countCheckedServers(self, value):
max = self.serversChecked.amount_of_servers_int
self.serversCheckedtoScreen.setText(f"Servers Checked: {value} / " + str(max))
def toScreen(self, value):
self.textOutput.appendPlainText(value)
def pbar_step(self, value):
self.pbar.setValue(int(value))
def maxPbar(self,value):
self.pbar.setMaximum(value)
def disableButton(self, n): # added extra function to check but makes no difference
if n == 1:
self.countBtn.setDisabled(True)
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec())
正如@musicamante 在评论中正确指出的那样,我在
下留下了一行代码def onButtonClick(self):
self.serversChecked = Worker()
self.textOutput.clear()
移除后
self.serversChecked.amount_of_servers.connect(self.setupUi)
按照他的建议问题已经解决了。我已经要求他创建一个 asnwer,这样我就可以信任他,我希望他能尽快这样做。因此,我还没有标记为完成。
同时复制他的原始评论:
You're calling
self.setupUi
everytime the worker is started, so you're creating a new UI. That signal is not emitted instantly, but asynchronously. So, the button is disabled, but right after that the thread is actually started, which creates a new UI, with an enabled button. Removeself.serversChecked.amount_of_servers.connect(self.setupUi)
.
可悲的是,代码盲目是一回事,但是,有一些杰出的人愿意提供帮助。再次感谢@musicamante