2012-01-11 62 views
15

我最近纔開始編程和Python(PyQt)特別是。我有我的主要QMainWindow類。但我想將它與UI小部件分開,以便所有窗口的東西(菜單,工具欄,常用按鈕)都在QMainWindow中,但所有程序/ UI特定的小部件(按鈕,組合框,圖像,複選框等)都在單獨的QWidget類。但我不確定我是否正確做這件事。PyQt - 如何添加單獨的UI小部件到QMainWindow

  1. 我有佈局的一個問題 - 看不見的東西被覆蓋了菜單,使他們不被鼠標點擊,我覺得我沒有正確加入我的UI控件到主窗口

下面是我如何做到這一點:

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. 我見過其他的Python程序,其中應用程序被分解成很多小的代碼文件(據我瞭解,擁有一切在主類是不可讀或無法管理)。

關於將代碼分解爲小塊的建議是什麼?如何更好地完成?或者對於用戶界面,它可以都在一個大的地方?我應該把UI代碼/類分解成單獨的文件嗎?

謝謝。

[解決]

我發現我的錯誤 - 我刪除從UI控件類main_widget(現在所有的UI控件直接放置在UI類的小部件本身),只有做到這一點:

self.main_layout.addWidget(self.form_widget) 

沒有更多的菜單問題

+0

我發現我的錯誤。我已經從UI小部件中刪除了main_widget,並將其本身用作所有其他小部件(按鈕,編輯線等)的控件,而主類僅實例化UI部件(請參見上文) - 解決了菜單問題。 – linuxoid 2012-01-12 01:53:18

回答

20

你在尋找類似的東西嗎?我真的不知道你的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_()) 
7

我會建議使用Qt Designer創建儘可能多的用戶界面儘可能的。

你會發現以這種方式嘗試佈局等等會更容易,並且它會自動將大部分UI相關的東西與其他應用程序邏輯分開。對主窗口以及任何對話框執行此操作都很簡單。

然後使用pyuic4從所有ui文件中編譯python模塊,並將它們全部放在它們自己的子包中。

我建議在編譯ui文件時使用-w標誌。這將生成一個簡單的包裝器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實例的屬性。

我不會擔心在開發過程中將應用程序分成更小的模塊。這可能不是必要的 - 但是如果這樣做的話,一旦應用程序開始變得更加複雜,如何做到這一點將變得更加明顯。

沒有硬性規定 - 每個項目都不一樣。

+1

我曾經使用Qt設計器,但我不喜歡它生成的代碼,它看起來很糟糕,以後很難改變,它也增加了很多我並不需要的垃圾。這就是爲什麼我從頭開始寫自己的UI。這樣我就可以控制每一行代碼。雖然我可能會失去一些東西,但我會學習。謝謝您的回覆。 – linuxoid 2012-01-12 01:51:02

+5

@ user665327。你完全誤解了生成的模塊的用途。他們不適合編輯。它們僅用於_importing_。我不會說手工編寫UI代碼有什麼問題,但是由於不使用Qt Designer而錯失了很多。至少,你應該用它作爲實驗的工具。即使你不使用'pyuic'生成的代碼,你仍然可以通過看看它是如何做的事情來學習很多東西(當涉及到佈局管理時尤其如此)。 – ekhumoro 2012-01-12 03:20:02

8
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()) 

正確的方法!

相關問題