PyQt - как добавить отдельный виджет пользовательского интерфейса в QMainWindow
Я только недавно начал программировать и Python (PyQt) в частности. У меня есть мой основной класс QMainWindow
. Но я хотел отделить его от виджета пользовательского интерфейса, так что все материалы Windows (меню, панели инструментов, общие кнопки) находятся в QMainWindow
, но все специальные виджеты для программ/пользовательских интерфейсов (pusgbuttons, comboboxes, images, checkboxes и т.д.) Находятся в отдельный класс QWidget
. Но я не уверен, что я делаю это правильно.
- У меня проблема с макетами - что-то невидимое закрывает меню, так что они не могут щелкнуть мышью, я думаю, что я не добавляю свой виджет пользовательского интерфейса в главное окно правильно
Вот как я это делаю:
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)
- Я видел другие программы на Python, где приложения разбиты на множество небольших файлов кода (как я понимаю, все, что включено в основной класс, нечитабельно или неуправляемо).
Как вы предлагаете разбить код на мелкие кусочки? Как это лучше сделать? Или для пользовательского интерфейса все это может быть в одном большом месте? Должен ли я вообще нарушать код/классы пользовательского интерфейса в отдельный файл?
Спасибо.
[решено]
Я нашел свою ошибку - я удалил main_widget из класса виджета пользовательского интерфейса (теперь все виджеты пользовательского интерфейса размещаются непосредственно в виджетах класса UI), и только это:
self.main_layout.addWidget(self.form_widget)
больше проблем с меню
Ответы
Ответ 1
Вы ищете что-то вроде этого? Я не уверен, что ваш main_widget
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_())
Ответ 2
import sys
from PyQt4 import QtCore, QtGui
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.form_widget = FormWidget(self)
_widget = QtGui.QWidget()
_layout = QtGui.QVBoxLayout(_widget)
_layout.addWidget(self.form_widget)
self.setCentralWidget(_widget)
class FormWidget(QtGui.QWidget):
def __init__(self, parent):
super(FormWidget, self).__init__(parent)
self.__controls()
self.__layout()
def __controls(self):
self.label = QtGui.QLabel("Name for backdrop")
self.txted = QtGui.QLineEdit()
self.lbled = QtGui.QLabel("Select a readNode")
self.cmbox = QtGui.QComboBox()
def __layout(self):
self.vbox = QtGui.QVBoxLayout()
self.hbox = QtGui.QHBoxLayout()
self.h2Box = QtGui.QHBoxLayout()
self.hbox.addWidget(self.label)
self.hbox.addWidget(self.txted)
self.h2Box.addWidget(self.lbled)
self.h2Box.addWidget(self.cmbox)
self.vbox.addLayout(self.hbox)
self.vbox.addLayout(self.h2Box)
self.setLayout(self.vbox)
def main():
app = QtGui.QApplication(sys.argv)
win = MainWindow()
win.show()
app.exec_()
if __name__ == '__main__':
sys.exit(main())
правильный путь!!!
Ответ 3
Я бы рекомендовал использовать Qt Designer для создания максимально возможного интерфейса.
Вам будет намного легче экспериментировать с макетами и т.д. таким образом, и он автоматически сохранит большую часть материала, связанного с пользовательским интерфейсом, отдельно от остальной части вашей логики приложения. Сделайте это для главного окна, а также для любых диалоговых окон, как бы прост.
Затем используйте pyuic4
для компиляции модулей python из всех файлов ui
и поместите их все вместе в свой собственный подпакет.
Я бы рекомендовал использовать флаг -w
при компиляции файлов ui
. Это создаст простой UI-класс оболочки, который может быть подклассифицирован напрямую.
Итак, ваше главное окно будет выглядеть примерно так:
from ui.mainwindow import MainWindowUI
class MainWindow(MainWindowUI):
def __init__(self):
super(MainWindow, self).__init__()
# connect signals...
# do other setup stuff...
Обратите внимание, что все виджеты, добавленные в Qt Designer, теперь доступны непосредственно как атрибуты экземпляра MainWindow
.
Я бы не стал беспокоиться о том, чтобы разбить приложение на более мелкие модули до тех пор, пока он не появится в разработке. Возможно, это не обязательно, но если это произойдет, станет более очевидным, как это сделать, когда приложение станет более сложным.
Нет жестких и быстрых правил - каждый проект отличается.