Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt - how to add separate UI widget to QMainWindow

Tags:

I've only recently started programming and Python (PyQt) in particular. I have my main QMainWindow class. But I wanted to separate it from UI widgets, so that all windows stuff (menus, toolbars, common buttons) are in QMainWindow, but all program/UI specific widgets (pusgbuttons, comboboxes, images, checkboxes etc.) are in a separate QWidget class. But I'm not sure if I'm doing this right.

  1. I have a problem with layouts - something invisible is covering the menus so that they're not clickable by mouse, I think I'm not adding my UI widget to the main window correctly

Here's how I do it:

class MyMainWindow(QMainWindow):     def __init__(self, parent = None):         super(MyMainWindow, self).__init__(parent)          self.main_widget = QWidget(self)         ...         self.form_widget = FormWidget(self)          #This is my UI widget          self.main_layout = QVBoxLayout(self.main_widget)         self.main_layout.sizeConstraint = QLayout.SetDefaultConstraint         self.main_layout.addWidget(self.form_widget.main_widget)          #form_widget has its own main_widget where I put all other widgets onto          self.main_widget.setLayout(self.main_layout)         self.setCentralWidget(self.main_widget) 
  1. I've seen other Python programs where applications are broken into a lot of small files of code (as I understand it, having everything in on main class is unreadable or unmanageable).

What's your suggestion about breaking code into small pieces? How's it better done? Or for UI it can all be in one big place? Should I break UI code/classes into separate file at all?

Thank you.

[SOLVED]

I found my mistake - I deleted the main_widget from the UI widget class (now all UI widgets are placed directly on the UI class widget itself) and only do this:

self.main_layout.addWidget(self.form_widget) 

no more problems with menus

like image 462
linuxoid Avatar asked Jan 11 '12 05:01

linuxoid


People also ask

Is PyQt a GUI widgets toolkit?

PyQt is a toolkit for graphical user interface (GUI) widgets.

How do I import QWidget?

QtWidgets import QApplication, QWidget # Only needed for access to command line arguments import sys # You need one (and only one) QApplication instance per application. # Pass in sys. argv to allow command line arguments for your app. # If you know you won't use command line arguments QApplication([]) works too.

What is QMainWindow in PyQt5?

Qt Main Window Framework A main window provides a framework for building an application's user interface. Qt has QMainWindow and its related classes for main window management. QMainWindow has its own layout to which you can add QToolBars, QDockWidgets, a QMenuBar, and a QStatusBar.


2 Answers

Are you looking for something like this? I'm not really sure what your main_widget is

from PyQt4.QtCore import * from PyQt4.QtGui  import *  import sys  class MyMainWindow(QMainWindow):      def __init__(self, parent=None):          super(MyMainWindow, self).__init__(parent)         self.form_widget = FormWidget(self)          self.setCentralWidget(self.form_widget)    class FormWidget(QWidget):      def __init__(self, parent):                 super(FormWidget, self).__init__(parent)         self.layout = QVBoxLayout(self)          self.button1 = QPushButton("Button 1")         self.layout.addWidget(self.button1)          self.button2 = QPushButton("Button 2")         self.layout.addWidget(self.button2)          self.setLayout(self.layout)  app = QApplication([]) foo = MyMainWindow() foo.show() sys.exit(app.exec_()) 
like image 114
Jeff Avatar answered Oct 02 '22 12:10

Jeff


I would recommend using Qt Designer to create as much of the UI as possible.

You will find it much easier to experiment with layouts and so forth that way, and it will automatically keep most of the UI related stuff separate from the rest of your application logic. Do this for the main window, and also for any dialog boxes, however simple.

Then use pyuic4 to compile python modules from all the ui files, and put them all together in their own sub-package.

I would recommend using the -w flag when compiling ui files. This will generate a simple wrapper UI class that can be subclassed directly.

So your main window would end up looking something like this:

from ui.mainwindow import MainWindowUI  class MainWindow(MainWindowUI):     def __init__(self):         super(MainWindow, self).__init__()         # connect signals...         # do other setup stuff... 

Note that all the widgets added in Qt Designer are now accessible directly as attributes of the MainWindow instance.

I would not worry about breaking your application up into smaller modules until later on in development. It may not turn out to be necessary - but if it does, it will become more obvious how to do this once the application starts to become more complex.

There are no hard and fast rules - every project is different.

like image 21
ekhumoro Avatar answered Oct 02 '22 14:10

ekhumoro