I'm pretty new to python and especially to pyqt4 but I would like to learn it right.
Therefore I want to build my new learning project in three different files. One main.py file in which I call everything. One by the QDesigner generated UI file (Main_Ui.py) and one Main_Functions.py file in which I would like to keep all my functions.
My first question would therefore be whether this is a "good programming style" or should I do it in a different way?
During the implementation of my idea I got stuck with calling the function. The console says "TypeError: connect() slot argument should be a callable or a signal, not 'NoneType'".
Could you please help me and tell me what I did wrong as I googled now nearly all day long and I could not find anything that would fit or I didn't understood it. It would be really great and would help me a lot learning how to do it right :)
Thank you very much :)
Here is my examplary code so far:
Main.py
import sys
from PyQt4 import QtGui, QtCore
from Main_Ui import Ui_MainWindow
import Main_Functions as f
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.btn1.clicked.connect(f.download(self.ui))
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp = MainWindow()
myapp.show()
sys.exit(app.exec_())
Main_Functions.py
def download(window):
window.completed = 0
while window.completed < 100:
window.completed += 0.0001
window.progress.setValue(window.completed)
And the probably not so interesting Main_Ui.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'Main.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(1000, 848)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.gridLayoutWidget = QtGui.QWidget(self.centralwidget)
self.gridLayoutWidget.setGeometry(QtCore.QRect(210, 150, 2, 2))
self.gridLayoutWidget.setObjectName(_fromUtf8("gridLayoutWidget"))
self.gridLayout = QtGui.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.tableWidget = QtGui.QTableWidget(self.centralwidget)
self.tableWidget.setGeometry(QtCore.QRect(50, 120, 256, 192))
self.tableWidget.setObjectName(_fromUtf8("tableWidget"))
self.tableWidget.setColumnCount(1)
self.tableWidget.setRowCount(1)
item = QtGui.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(0, item)
item = QtGui.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(0, item)
self.progress = QtGui.QProgressBar(self.centralwidget)
self.progress.setGeometry(QtCore.QRect(180, 550, 118, 23))
self.progress.setProperty("value", 24)
self.progress.setObjectName(_fromUtf8("progress"))
self.btn1 = QtGui.QPushButton(self.centralwidget)
self.btn1.setGeometry(QtCore.QRect(490, 200, 75, 23))
self.btn1.setObjectName(_fromUtf8("btn1"))
self.lbl1 = QtGui.QLabel(self.centralwidget)
self.lbl1.setGeometry(QtCore.QRect(400, 200, 46, 13))
self.lbl1.setObjectName(_fromUtf8("lbl1"))
self.txt1 = QtGui.QLineEdit(self.centralwidget)
self.txt1.setGeometry(QtCore.QRect(330, 160, 113, 20))
self.txt1.setObjectName(_fromUtf8("txt1"))
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1000, 21))
self.menubar.setObjectName(_fromUtf8("menubar"))
self.menuDatei = QtGui.QMenu(self.menubar)
self.menuDatei.setObjectName(_fromUtf8("menuDatei"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.actionSchlie_en = QtGui.QAction(MainWindow)
self.actionSchlie_en.setObjectName(_fromUtf8("actionSchlie_en"))
self.menuDatei.addAction(self.actionSchlie_en)
self.menubar.addAction(self.menuDatei.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
item = self.tableWidget.verticalHeaderItem(0)
item.setText(_translate("MainWindow", "T", None))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "1", None))
self.btn1.setText(_translate("MainWindow", "PushButton", None))
self.lbl1.setText(_translate("MainWindow", "TextLabel", None))
self.menuDatei.setTitle(_translate("MainWindow", "Datei", None))
self.actionSchlie_en.setText(_translate("MainWindow", "Schließen", None))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
The problem is your connection
self.ui.btn1.clicked.connect(f.download(self.ui))
You need to pass a callback to the connect function. Here, you're actually calling the download function (which returns None) and passing the results to connect.
You need to do this instead
self.ui.btn1.clicked.connect(lambda: f.download(self.ui))
It does often make sense to separate non-gui business logic out into separate modules. This allows them to be re-used in other modules and GUI's. However, in your case, you're performing GUI modification in code outside your GUI class. That's generally not a very good design and it would be better for you to define those functions inside your MainWindow class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With