Issue
I am trying to build a simple internet speed test app using pyqt5 I am a beginner and trying to build small apps to learn GUI basics So here is the code whenever i try to change label text from my thread function is says that self has no member named label_7. ignore the print statements i was just using them for debugging
def Update_values(self,MainWindow):
_translate = QtCore.QCoreApplication.translate
self.label_7.setText(_translate("MainWindow", "Download Speed : " + str(down)))
at the upper part of code i got error Thank you in advance
from PyQt5 import QtCore, QtGui, QtWidgets
import speedtest as st
speed_test = st.Speedtest()
download = speed_test.download()
val = 0
val1 = 0
val3 = 0
down = 0
up = 0
pin = 0
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(331, 307)
font = QtGui.QFont()
font.setFamily("Lucida Sans Unicode")
MainWindow.setFont(font)
MainWindow.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
MainWindow.setMouseTracking(False)
MainWindow.setTabletTracking(False)
MainWindow.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
MainWindow.setDocumentMode(False)
MainWindow.setTabShape(QtWidgets.QTabWidget.Triangular)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.label = QtWidgets.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setFamily("Comic Sans MS")
font.setPointSize(16)
self.label.setFont(font)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 3)
self.line_2 = QtWidgets.QFrame(self.centralwidget)
self.line_2.setFrameShape(QtWidgets.QFrame.HLine)
self.line_2.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line_2.setObjectName("line_2")
self.gridLayout.addWidget(self.line_2, 1, 0, 1, 3)
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 2)
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setFrameShape(QtWidgets.QFrame.NoFrame)
self.label_4.setObjectName("label_4")
self.gridLayout.addWidget(self.label_4, 3, 0, 1, 2)
self.label_3 = QtWidgets.QLabel(self.centralwidget)
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 4, 0, 1, 2)
self.label_7 = QtWidgets.QLabel(self.centralwidget)
self.label_7.setObjectName("label_7")
self.gridLayout.addWidget(self.label_7, 5, 0, 1, 2)
self.label_8 = QtWidgets.QLabel(self.centralwidget)
self.label_8.setObjectName("label_8")
self.gridLayout.addWidget(self.label_8, 6, 0, 1, 1)
self.progressBar = QtWidgets.QProgressBar(self.centralwidget)
self.progressBar.setProperty("value", 24)
self.progressBar.setTextVisible(False)
self.progressBar.setObjectName("progressBar")
self.gridLayout.addWidget(self.progressBar, 7, 0, 1, 3)
self.check1 = QtWidgets.QCheckBox(self.centralwidget)
self.check1.setObjectName("check1")
self.check1.stateChanged.connect(self.check_1)
self.gridLayout.addWidget(self.check1, 8, 0, 1, 1)
self.check2 = QtWidgets.QCheckBox(self.centralwidget)
self.check2.setObjectName("check2")
self.check2.stateChanged.connect(self.check_2)
self.gridLayout.addWidget(self.check2, 8, 1, 1, 1)
self.check3 = QtWidgets.QCheckBox(self.centralwidget)
self.check3.setObjectName("check3")
self.check3.stateChanged.connect(self.check_3)
self.gridLayout.addWidget(self.check3, 8, 2, 1, 1)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.start_test)
self.gridLayout.addWidget(self.pushButton, 9, 0, 1, 3)
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 331, 22))
self.menubar.setObjectName("menubar")
self.menuFile = QtWidgets.QMenu(self.menubar)
self.menuFile.setObjectName("menuFile")
self.menuAbout = QtWidgets.QMenu(self.menubar)
self.menuAbout.setObjectName("menuAbout")
MainWindow.setMenuBar(self.menubar)
self.actionSave_Results = QtWidgets.QAction(MainWindow)
self.actionSave_Results.setCheckable(False)
self.actionSave_Results.setChecked(False)
self.actionSave_Results.setObjectName("actionSave_Results")
self.actionChange_Save_Directory = QtWidgets.QAction(MainWindow)
self.actionChange_Save_Directory.setObjectName("actionChange_Save_Directory")
self.actionDeveloper = QtWidgets.QAction(MainWindow)
self.actionDeveloper.setObjectName("actionDeveloper")
self.menuFile.addAction(self.actionSave_Results)
self.menuFile.addAction(self.actionChange_Save_Directory)
self.menuAbout.addAction(self.actionDeveloper)
self.menubar.addAction(self.menuFile.menuAction())
self.menubar.addAction(self.menuAbout.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Internet Speed Test"))
self.label.setText(_translate("MainWindow", "Internet Speed Test By FATE"))
self.label_2.setText(_translate("MainWindow", "Status : Connected"))
self.label_4.setText(_translate("MainWindow", "Ping : --"))
self.label_3.setText(_translate("MainWindow", "Upload Speed : --"))
self.label_7.setText(_translate("MainWindow", "Download Speed : --"))
self.label_8.setText(_translate("MainWindow", "Progress :"))
self.check1.setText(_translate("MainWindow", "Download"))
self.check2.setText(_translate("MainWindow", "Upload"))
self.check3.setText(_translate("MainWindow", "Ping"))
self.pushButton.setText(_translate("MainWindow", "Start"))
self.menuFile.setTitle(_translate("MainWindow", "File"))
self.menuAbout.setTitle(_translate("MainWindow", "About"))
self.actionSave_Results.setText(_translate("MainWindow", "Save Results"))
self.actionChange_Save_Directory.setText(_translate("MainWindow", "Change Save Directory"))
self.actionDeveloper.setText(_translate("MainWindow", "Developer"))
self.Update_values(MainWindow)
def Update_values(self,MainWindow):
_translate = QtCore.QCoreApplication.translate
self.label_7.setText(_translate("MainWindow", "Download Speed : " + str(down)))
# self.label_7.setText(_translate("MainWindow", "Download Speed : 10"))
print(down)
print(up)
print(pin)
def check_1(self, state):
global val
print(val)
if state != self.check1.isChecked():
val += 1
print("YESH "+ str(val))
else:
val -= 1
print("NO" + str(val))
def check_2(self, state):
global val1
print(val1)
if state != self.check1.isChecked():
val1 += 1
print("YESH "+ str(val1))
else:
val1 -= 1
print("NO" + str(val1))
def check_3(self, state):
global val3
print(val3)
if state != self.check1.isChecked():
val3 += 1
print("YESH "+ str(val3))
else:
val3 -= 1
print("NO" + str(val3))
def start_test(self):
self.threadclass = Thread()
self.threadclass.start()
class Thread(QtCore.QThread,Ui_MainWindow):
def __init__(self,parent = None):
super(Thread, self).__init__(parent)
def run(self):
if val == 1:
download = speed_test.download()
download_mbs = round(download / (10**6), 2)
global down
down = download_mbs
self.Update_values(Ui_MainWindow)
if val1 == 1:
upload = speed_test.upload()
upload_mbs = round(upload / (10**6), 2)
global up
up = upload_mbs
if val3 == 1:
ping = speed_test.results.ping
global pin
pin = ping
print("DONE")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Solution
First of all, you should not modify the code generated by Qt Designer, so in my next solution you must regenerate the .py generated by pyuic and call it gui.py: python -m pyuic5 your_ui.ui -o gui.py
.
Another error you have is that you should not update the GUI from another thread, nor use global variables since they are prone to generating silent errors, instead you should use the signals as shown below:
from enum import Flag, auto
import threading
from PyQt5 import QtCore, QtGui, QtWidgets
import speedtest
from gui import Ui_MainWindow
class Task(Flag):
NONE = auto()
DOWNLOAD = auto()
UPLOAD = auto()
PING = auto()
class SpeedtestWrapper(QtCore.QObject):
started = QtCore.pyqtSignal()
finished = QtCore.pyqtSignal()
downloaded = QtCore.pyqtSignal(float)
uploaded = QtCore.pyqtSignal(float)
pinged = QtCore.pyqtSignal(float)
def start(self, flag):
threading.Thread(target=self._execute, args=(flag,), daemon=True).start()
def _execute(self, flag):
self.started.emit()
speed_test = speedtest.Speedtest()
if flag & Task.DOWNLOAD:
download = speed_test.download()
download_mbs = round(download / (10 ** 6), 2)
self.downloaded.emit(download_mbs)
if flag & Task.DOWNLOAD:
upload = speed_test.upload()
upload_mbs = round(upload / (10 ** 6), 2)
self.uploaded.emit(upload_mbs)
if flag & Task.DOWNLOAD:
ping = speed_test.results.ping
self.pinged.emit(ping)
self.finished.emit()
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self._flag = Task.NONE
self.speed_wrapper = SpeedtestWrapper()
self.speed_wrapper.started.connect(self.on_started)
self.speed_wrapper.finished.connect(self.on_finished)
self.speed_wrapper.downloaded.connect(self.on_downloaded)
self.speed_wrapper.uploaded.connect(self.on_uploaded)
self.speed_wrapper.pinged.connect(self.on_pinged)
@QtCore.pyqtSlot()
def start_test(self):
if self._flag != Task.NONE:
self.speed_wrapper.start(self._flag)
@QtCore.pyqtSlot(int)
def check_1(self, state):
if state:
self._flag |= Task.DOWNLOAD
else:
self._flag &= ~Task.DOWNLOAD
@QtCore.pyqtSlot(int)
def check_2(self, state):
if state:
self._flag |= Task.UPLOAD
else:
self._flag &= ~Task.UPLOAD
@QtCore.pyqtSlot(int)
def check_3(self, state):
if state:
self._flag |= Task.PING
else:
self._flag &= ~Task.PING
@QtCore.pyqtSlot()
def on_started(self):
self.label_7.setText(self.tr("Download Speed: --"))
self.label_3.setText(self.tr("Upload Speed: --"))
self.label_4.setText(self.tr("Ping Speed: --"))
self.pushButton.setEnabled(False)
@QtCore.pyqtSlot()
def on_finished(self):
self.pushButton.setEnabled(True)
@QtCore.pyqtSlot(float)
def on_downloaded(self, download):
self.label_7.setText(self.tr("Download Speed: %f" % download))
@QtCore.pyqtSlot(float)
def on_uploaded(self, upload):
self.label_3.setText(self.tr("Upload Speed: %f" % upload))
@QtCore.pyqtSlot(float)
def on_pinged(self, ping):
self.label_4.setText(self.tr("Ping Speed: %f" % ping))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
Answered By - eyllanesc
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.