4


I am trying to create a PyQt application that has both status bar and a menu bar with other Widgets in the window. Below is the code which I managed to get it run with class QtGui.QMainWindow method. But as I intend to add further features, I realise I must use QtGui.QWidget instead.

Here is the code:

import sys
from PyQt4 import QtGui, QtCore

### How can I use QtGui.QWidget here??? ###

class Example(QtGui.QMainWindow):                                  
     def __init__(self):
          super(Example, self).__init__()
          self.initUI()

     def initUI(self):               

        QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))    
        self.setToolTip('This is a <b>QWidget</b> Window widget')

        exitAction = QtGui.QAction(QtGui.QIcon('exit-icon-2.png'), '&Exit', self)

        exitAction.setShortcut('Ctrl+Q')                        
        exitAction.setStatusTip('Exit/Terminate application')   

        exitAction.triggered.connect(QtGui.qApp.quit)           

        self.statusBar()                                       

        menubar = self.menuBar()                                
        menubar.setToolTip('This is a <b>QWidget</b> for MenuBar')                                

        fileMenu = menubar.addMenu('&File')                     
        fileMenu.addAction(exitAction)                          
        toolbar = self.addToolBar('Exit')                       
        toolbar.addAction(exitAction)                           

        qbtn = QtGui.QPushButton('Quit', self)                  

        qbtn.setToolTip('This is a <b>QPushButton</b> widget')  
        qbtn.clicked.connect(self.launchAAA)                    
        qbtn.resize(qbtn.sizeHint())                           
        qbtn.move(170, 190)                                     



        self.setGeometry(500, 180, 400, 400)                    
        self.setWindowTitle('Quit button with Message')        
        self.show()                                            

    def launchAAA(self, event):

        reply = QtGui.QMessageBox.question(self, 'Message',
        "Are you sure to quit?", QtGui.QMessageBox.Yes | 
        QtGui.QMessageBox.No, QtGui.QMessageBox.No)

        if reply == QtGui.QMessageBox.Yes:  
           QtGui.QApplication.quit()
        else:
           pass                                              


def main():

   app = QtGui.QApplication(sys.argv)                          
   ex=Example()

   sys.exit(app.exec_())                                       


if __name__ == '__main__':
   main()  

I am under the impression that menu bar and title bars can be created using QWidget method, but here it doesn't work. I intend to add an LCD function to the application using QtGui.QLCDNumber.

Any suggestions on how to fix the above problem. Thanks

AdrienW
  • 3,092
  • 6
  • 29
  • 59
SamAct
  • 529
  • 4
  • 23
  • 1
    @Mailerdaimon QWidget is having features like LCD Display, vbox and hbox functions that I might later need? I feel confused at your question, can you please tell me more. – SamAct Jul 12 '16 at 07:29
  • 1
    A normal approach is to create a QMainWindow and set a central QWidget for this Window using `void QMainWindow::setCentralWidget(QWidget * widget)`. Plus: QMainWindow is inherited from QWidget which means it has all the features a QWidget has plus more. – Mailerdaimon Jul 12 '16 at 07:34
  • @Mailerdaimon so QMainWindow has all the inherited features from QWidget so it should be fine to use it. And setting a central QWidget should fix my problems, can you guide me on any changes that would go on the above code? – SamAct Jul 12 '16 at 07:41
  • 1
    What you are missing is adding the `qbtn` to the QMainWindow. You can either do this directly by using `setCentralWidget` or, what I suggest, create a new Widget and set a Layout to this Widget, add your `qbtn` to the Layout and set the Widget as centralWidget. This allows you to add multiple layouts and widgets to the main window. – Mailerdaimon Jul 12 '16 at 07:46

3 Answers3

3

You could just move your buttons/labels/etc. to a QWidget, and add this widget to the main window. Here is how it could look like (I changed the imports so that it is a bit more readable).

Your content widget class :

class ExampleContent(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        self.initUI()

    def initUI(self):        
        qbtn = QPushButton('Quit', self)
        qbtn.setToolTip('This is a <b>QPushButton</b> widget')
        qbtn.clicked.connect(self.launchAAA)                 
        qbtn.resize(qbtn.sizeHint())                           
        qbtn.move(170, 190)

    def launchAAA(self):
        reply = QMessageBox.question(self, 'Message',
        "Are you sure to quit?", QMessageBox.Yes | 
        QMessageBox.No, QMessageBox.No)

        if reply == QMessageBox.Yes:  
            QApplication.quit()
        else:
            pass

Add it to the main window :

class Example(QMainWindow):                                  
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):               
        QToolTip.setFont(QFont('SansSerif', 10))
        self.setToolTip('This is a <b>QWidget</b> Window widget')

        exitAction = QAction(QIcon('exit-icon-2.png'), '&Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit/Terminate application')
        exitAction.triggered.connect(qApp.quit)

        self.statusBar()

        menubar = self.menuBar()        
        menubar.setToolTip('This is a <b>QWidget</b> for MenuBar')

        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(exitAction)
        toolbar = self.addToolBar('Exit')
        toolbar.addAction(exitAction)

        # create the widget here
        content = ExampleContent(self)
        self.setCentralWidget(content)

        self.setGeometry(500, 180, 400, 400)     
        self.setWindowTitle('Quit button with Message')
        self.show()

And everything just works as before, except that you new have a QWidget in the middle, instead of a QMainWindow. Hope that helped !

AdrienW
  • 3,092
  • 6
  • 29
  • 59
2

Here is a working solution using your code. I added a centralWidget and a centralLayout to the QMainWindow which now holds your qbtn:

import sys
from PyQt4 import QtGui, QtCore

class Example(QtGui.QMainWindow):                                  
     def __init__(self):
          super(Example, self).__init__()
          self.initUI()

     def initUI(self):               

        QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))    
        self.setToolTip('This is a <b>QWidget</b> Window widget')

        exitAction = QtGui.QAction(QtGui.QIcon('exit-icon-2.png'), '&Exit', self)

        exitAction.setShortcut('Ctrl+Q')                        
        exitAction.setStatusTip('Exit/Terminate application')   

        exitAction.triggered.connect(QtGui.qApp.quit)           

        self.statusBar()                                       

        menubar = self.menuBar()                                
        menubar.setToolTip('This is a <b>QWidget</b> for MenuBar')                                

        fileMenu = menubar.addMenu('&File')                     
        fileMenu.addAction(exitAction)                          
        toolbar = self.addToolBar('Exit')                       
        toolbar.addAction(exitAction)                        

        # Create a central Widgets
        centralWidget = QtGui.QWidget()

        # Create a Layout for the central Widget
        centralLayout = QtGui.QHBoxLayout()



        qbtn = QtGui.QPushButton('Quit', self)                  

        qbtn.setToolTip('This is a <b>QPushButton</b> widget')  
        qbtn.clicked.connect(self.launchAAA)                    
        qbtn.resize(qbtn.sizeHint())                           
        qbtn.move(170, 190)      

        # Add the Button to the Layout
        centralLayout.addWidget(qbtn)  

        # Set the Layout
        centralWidget.setLayout(centralLayout)

        # Set the Widget
        self.setCentralWidget(centralWidget)     

        self.setGeometry(500, 180, 400, 400)                    
        self.setWindowTitle('Quit button with Message')        
        self.show()                                            

     def launchAAA(self, event):

        reply = QtGui.QMessageBox.question(self, 'Message',
        "Are you sure to quit?", QtGui.QMessageBox.Yes | 
        QtGui.QMessageBox.No, QtGui.QMessageBox.No)

        if reply == QtGui.QMessageBox.Yes:  
           QtGui.QApplication.quit()
        else:
           pass                                              


def main():

   app = QtGui.QApplication(sys.argv)                          
   ex=Example()

   sys.exit(app.exec_())                                       


if __name__ == '__main__':
   main()  
Mailerdaimon
  • 6,003
  • 3
  • 35
  • 46
  • The code seems to work fine, with some fine tuning. But I couldn't get the pushbutton to hold its size as we increase or decrease the window size. `qbtn.resize(qbtn.sizeHint())` seem to have no effect in this. Any changes that I should make? – SamAct Jul 12 '16 at 10:18
  • I think this should be a new question. This makes it easier for others to find the solution if they have the same problem. – Mailerdaimon Jul 12 '16 at 10:38
0

You can also use a combination of QMainWindow and QWidget.

I have found this useful in some cases. You can add statusbar and menubar to the MainWindow section and the widgets to the QWidget area.

import sys
from PyQt4 import QtCore, QtGui


class MainWindow(QtGui.QMainWindow):

def __init__(self, parent=None):

    super(MainWindow, self).__init__(parent)

    self.win_widget = WinWidget(self)
    widget = QtGui.QWidget()
    layout = QtGui.QVBoxLayout(widget)
    layout.addWidget(self.win_widget)
    self.setCentralWidget(widget)

    self.statusBar().showMessage('Ready')

    self.setGeometry(300, 300, 450, 250)
    self.setWindowTitle('Test')  
    self.setWindowIcon (QtGui.QIcon('logo.png'))
    self.show()

    self.win_widget = WinWidget (self)



class WinWidget (QtGui.QWidget) : 

def __init__(self, parent): 
    super (WinWidget , self).__init__(parent)
    self.__controls()
    #self.__layout()

def __controls(self):

    self.qbtn = QtGui.QPushButton('Quit', self)
    self.qbtn. clicked.connect(QtCore.QCoreApplication.instance().quit)
    self.qbtn.setFixedSize (100,25)
    self.qbtn.move(50, 50)  


def main():

app = QtGui.QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())

if __name__ == '__main__':
main()
rainer
  • 3,295
  • 5
  • 34
  • 50