3

I have a PyQt5 Ui named guiNext.py and next.py which is refrencing the UI. How do I add function to the UI button? This is what I have and nothing happens when I run next.py and click on HELLO button.

guiNext.py:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'guiNext_001.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_nextGui(object):
    def setupUi(self, nextGui):
        nextGui.setObjectName("nextGui")
        nextGui.resize(201, 111)
        nextGui.setMinimumSize(QtCore.QSize(201, 111))
        nextGui.setMaximumSize(QtCore.QSize(201, 111))
        self.centralwidget = QtWidgets.QWidget(nextGui)
        self.centralwidget.setObjectName("centralwidget")
        self.helloBtn = QtWidgets.QPushButton(self.centralwidget)
        self.helloBtn.setGeometry(QtCore.QRect(10, 10, 181, 91))
        self.helloBtn.setObjectName("helloBtn")
        nextGui.setCentralWidget(self.centralwidget)

        self.retranslateUi(nextGui)
        QtCore.QMetaObject.connectSlotsByName(nextGui)

    def retranslateUi(self, nextGui):
        _translate = QtCore.QCoreApplication.translate
        nextGui.setWindowTitle(_translate("nextGui", "MainWindow"))
        self.helloBtn.setText(_translate("nextGui", "HELLO"))

and here is main file next.py:

#!usr/bin/env python
#-*- coding: utf-8 -*-

from PyQt5 import QtCore, QtGui, QtWidgets
from guiNext import Ui_nextGui

class mainProgram(Ui_nextGui):
    def __init__(self, parent=None):
        Ui_nextGui.__init__(self)
        self.setupUi(nextGui)
        self.helloBtn.clicked.connect(self.hello)

    def hello(self):
        print ("HELLO")

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    nextGui = QtWidgets.QMainWindow()
    ui = Ui_nextGui()
    ui.setupUi(nextGui)
    nextGui.show()
    sys.exit(app.exec_())
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
Amin Persia
  • 315
  • 2
  • 15

1 Answers1

7

The structure of your program is not quite right. There are several ways to use the ui files created by Qt Designer. The multiple-inheritance approach is possibly the most intuitive. This is what your code should look like:

from PyQt5 import QtCore, QtGui, QtWidgets
from guiNext import Ui_nextGui

class mainProgram(QtWidgets.QMainWindow, Ui_nextGui):
    def __init__(self, parent=None):
        super(mainProgram, self).__init__(parent)
        self.setupUi(self)
        self.helloBtn.clicked.connect(self.hello)

    def hello(self):
        print ("HELLO")

if __name__ == "__main__":

    import sys
    app = QtWidgets.QApplication(sys.argv)
    nextGui = mainProgram()
    nextGui.show()
    sys.exit(app.exec_())
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • Is `super(mainProgram, self).__init__(parent)` necessary? – Sherafati May 23 '20 at 08:36
  • 1
    @Sherafati Yes - otherwise `QMainWindow` would not be initialised properly. However, in Python 3 it can be simplified to `super().__init__(parent)`. – ekhumoro May 23 '20 at 09:19
  • But we you delete that expression, the program still works – Sherafati May 23 '20 at 09:22
  • @Sherafati You must be running different code. If you delete that line in my example, it will raise an error: `RuntimeError: super-class __init__() of type mainProgram was never called`. – ekhumoro May 23 '20 at 09:28
  • Thanks! Unlike OP's mainProgram class, your class inherits from QMainWindow, is this the reason you have not created an instance of the QMainWindow class? – Sherafati May 23 '20 at 09:31
  • 1
    @Sherafati Yes. If you follow the link to the pyqt docs in my answer, it shows three different ways to use the designer files. When you create an instance of `QMainWindow` yourself, it will automatically call its own `__init__`. But if you override `__init__` in a subclass, the base-class `__init__` must be called explicitly. – ekhumoro May 23 '20 at 09:36