Search code examples
pythonpyqtpyqt4qmessagebox

Qmessagebox not working


I'm using Ubuntu linux. I've used pyuic4 command and created a .py file and then added a messagebox to it.Here it is:

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(640, 480)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(190, 200, 98, 27))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 640, 25))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.about)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

def about(self):
    QtGui.QMessageBox.about(self, "Test", "This is a test.")

def retranslateUi(self, MainWindow):
    MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
    self.pushButton.setText(QtGui.QApplication.translate("MainWindow", "PushButton", None, QtGui.QApplication.UnicodeUTF8))
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_())

After experimenting a lot I found that it works if I change this: class Ui_MainWindow(object): to this: class Ui_MainWindow(QtGui.QMainWindow):

I made a big script and I don't know if it will cause any problem or if I'm doing the right thing .I'm just confused. Please help and pardon me if there's any problem in my writing. This is my first post.


Solution

  • I would not use the result of pyuic4 in the same way. In fact I would not use pyuic4 at all, but let's see the possibilities:

    Using pyuic4

    Say you have your ui file my_window.ui in which you create a QMainWindow widget named MainWindow. With Designer, you also added a link between the clicked action of the push button and a custom slot about() (do you know how to create a custom slot in designer ?). Now using the ui file can be done in 2 steps:

    1. You generate the python equivalent file ui_my_window.py with pyuic4:

      $ pyuic4 my_window.ui -o ui_my_window.py
      
    2. Then you create another python file (main.py) which will import the file ui_my_window.py. Do not modify the file generated by pyuic4 ! It will be overwritten if you rerun the pyuic4 command !

      $ cat main.py
      
      from PyQt4 import QtGui
      # import the class created py pyuic4
      from ui_my_window import Ui_MainWindow
      
      class MyMainWindow(QtGui.QMainWindow):
        def __init__(self, parent=None)
          QtGui.QMainWindow.__init__(self, parent)
          self.ui = Ui_MainWindow()
          self.ui.setupUi(self)
      
          # Beware that all widgets are now available through the self.ui attribute
          # Getting the push button is written:
          # self.ui.pushButton
      
        def about(self):
          # this is the custom slot created in Designer
          QtGui.QMessageBox.about(self, "Test", "This is a test.")
      
      if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        myMainWindow = MyMainWindow()
        myMainWindow.show()
        sys.exit(app.exec_())
      

    So now you have 3 files:

          $ ls
          main.py ui_my_window.py my_window.ui
    

    Just run python main.py to launch the GUI.

    Without using pyuic4

    PyQt4 provides a very usefull module when working with ui files: the uic module. In fact pyuic4 is using this module to generate the python file of the ui file. Using the module allows you to avoid the pyuic4 step (Beware: if you use icons in a resource file (.qrc), you still need to use the pyrcc4 tool and import the resulting file in your code).

    In your example, the code becomes very light:

    $ cat main.py
    
    import os
    from PyQt4 import QtGui
    # import the uic module
    from PyQt4 import uic
    
    class MyMainWindow(QtGui.QMainWindow):
      def __init__(self, parent=None)
        QtGui.QMainWindow.__init__(self, parent)
        # Load the ui file
        uic.loadUi(os.path.join(os.path.dirname(os.path.abspath(__file__)),"my_window.ui"), self)
    
        # Now in this case, all widgets can directly be accessed because the last argument
        # of loadUi is self.
        # Getting the push button is written:
        # self.pushButton
    
      def about(self):
        # this is the custom slot created in Designer
        QtGui.QMessageBox.about(self, "Test", "This is a test.")
    
    if __name__ == "__main__":
      import sys
      app = QtGui.QApplication(sys.argv)
      myMainWindow = MyMainWindow()
      myMainWindow.show()
      sys.exit(app.exec_())
    

    In this case you just have 2 files:

          $ ls
          main.py my_window.ui
    

    Again just run python main.py to launch the GUI.