I have everything sorted out with this little program of mine, however after I have inserted actual data i will be using into the dictionary, the button.setEnable(False) stopped working. Any ideas why?
code:
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)
)
This is all code i believe to be relevant, if more is needed, i can provide that.
Any ideas are welcome, as I am puzzled...
EDIT: as reqeusted, rest of code:
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())
CodePudding user response:
As correctly pointed out by @musicamante in the comments, I have left a line of code under
def onButtonClick(self):
self.serversChecked = Worker()
self.textOutput.clear()
After removing
self.serversChecked.amount_of_servers.connect(self.setupUi)
As per his advise the problem has been solved. I have asked him to create an asnwer so I can credit him and I hope he does so soon. As such i am not marking as complete yet.
Copy of his original comment in the meantime:
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)
.
Sadly, code blindness is a thing, however, there are some remarkable people willing to help. Again, Thank you @musicamante