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.
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)
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
PyQt is a toolkit for graphical user interface (GUI) widgets.
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.
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.
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_())
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.
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