【转】PyQt4 精彩实例分析 实例 17 综合布局实例
本实例综合应用前面介绍的布局方法实现一个复杂的窗口布局,实现效果图如下所示。其中包括了基本布局,
分割窗以及堆栈窗。



首先对整个窗体的构成进行一个整体的分析。最外层的是一个分割窗体 QSplitter,分割窗的左侧为一个
QListWidget,右侧为一个 QVBoxLayout 布局,包括一个堆栈窗 QStackWidget 和一个按钮布局,在堆
栈窗中包含 3 个窗体,每个窗体采用基本布局方式进行布局管理。窗体的布局可用如下的示意图表示。

堆栈窗中的 3 个页面分别定义了 3 个 QWidget 子类,包括“个人基本资料”页,由 BaseInfo 类实现,“联系
方式”页,由 Contact 类实现,“详细信息”页,由 Detail 类实现。
“个人基本资料”页与实例 12 中的内容一样,可直接引用。
“联系方式”页和“详细信息”页都是采用表格布局的方式进行布局管理,用法与前面所介绍的类似,此处不再
重复进行分析。
具体实现代码如下:
JakeyStackWidget.py:
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 import sys 5 from PyQt4.QtGui import * 6 from PyQt4.QtCore import * 7 8 from JakeyBasicInfo import BaseInfo 9 from JakeyContact import Contact 10 from JakeyDetail import Detail 11 12 13 QTextCodec.setCodecForTr(QTextCodec.codecForName("utf8")) 14 15 class StackDialog(QDialog): 16 def __init__(self, parent=None): 17 super(StackDialog,self).__init__(parent) 18 self.setWindowTitle(self.tr("Comprehensive layout examples")) 19 self.CreateStackDialog() 20 self.Layout() 21 self.ConcentSignalSlot() 22 23 def CreateStackDialog(self): 24 self.mainSplitter = QSplitter(Qt.Horizontal) 25 self.mainSplitter.setOpaqueResize(True) 26 27 self.listWidget = QListWidget(self.mainSplitter) 28 self.listWidget.insertItem(0, self.tr("Basic")) 29 self.listWidget.insertItem(1, self.tr("Contacts")) 30 self.listWidget.insertItem(2, self.tr("Detail")) 31 32 self.frame = QFrame(self.mainSplitter) 33 self.stack = QStackedWidget() 34 self.stack.setFrameStyle(QFrame.Panel|QFrame.Raised) 35 36 baseInfo = BaseInfo() 37 contact = Contact() 38 detail = Detail() 39 self.stack.addWidget(baseInfo) 40 self.stack.addWidget(contact) 41 self.stack.addWidget(detail) 42 43 self.btn_change = QPushButton(self.tr("Change")) 44 self.btn_close = QPushButton(self.tr("Close")) 45 46 def Layout(self): 47 buttonLayout = QHBoxLayout() 48 buttonLayout.addStretch(1) 49 buttonLayout.addWidget(self.btn_change) 50 buttonLayout.addWidget(self.btn_close) 51 52 mainLayout = QVBoxLayout(self.frame) 53 mainLayout.setMargin(10) 54 mainLayout.setSpacing(6) 55 mainLayout.addWidget(self.stack) 56 mainLayout.addLayout(buttonLayout) 57 58 layout = QHBoxLayout(self) 59 layout.addWidget(self.mainSplitter) 60 self.setLayout(layout) 61 62 def ConcentSignalSlot(self): 63 self.connect(self.listWidget, SIGNAL("currentRowChanged(int)"), self.stack, SLOT("setCurrentIndex(int)")) 64 self.connect(self.btn_close, SIGNAL("clicked()"), self, SLOT("close()")) 65 66 def main(): 67 app = QApplication(sys.argv) 68 main = StackDialog() 69 main.show() 70 app.exec_() 71 72 if __name__ == '__main__': 73 main()
JakeyBasicInfo.py:
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 import sys 5 from PyQt4.QtGui import * 6 from PyQt4.QtCore import * 7 8 9 QTextCodec.setCodecForTr(QTextCodec.codecForName("utf8")) 10 11 class BaseInfo(QWidget): 12 def __init__(self, parent=None): 13 super(BaseInfo, self).__init__(parent) 14 15 self.CreateControls() 16 self.Layout() 17 18 def CreateControls(self): 19 self.label_nickName = QLabel(self.tr("NickName:")) 20 self.label_userName = QLabel(self.tr("UserName:")) 21 self.label_sex = QLabel(self.tr("Sex:")) 22 self.label_department = QLabel(self.tr("Department:")) 23 self.label_age = QLabel(self.tr("Age:")) 24 self.label_remark = QLabel(self.tr("Remark:")) 25 self.label_remark.setFrameStyle(QFrame.Panel|QFrame.Sunken) 26 self.label_icon = QLabel(self.tr("Icon:")) 27 self.label_desc = QLabel(self.tr("Person Description:")) 28 29 self.label_picIcon = QLabel() 30 picIcon = QPixmap("image/2048.ico") 31 self.label_picIcon.setPixmap(picIcon) 32 self.label_picIcon.resize(picIcon.width(), picIcon.height()) 33 34 self.btn_change = QPushButton(self.tr("Change")) 35 self.lineEdit_nickName = QLineEdit() 36 self.lineEdit_userName = QLineEdit() 37 self.lineEdit_age = QLineEdit() 38 self.comboBox_sex = QComboBox() 39 self.comboBox_sex.insertItem(0, self.tr("M")) 40 self.comboBox_sex.insertItem(1, self.tr("F")) 41 self.textEdit_department = QTextEdit() 42 self.textEdit_desc = QTextEdit() 43 44 def Layout(self): 45 self.LeftLayout() 46 self.RightLayout() 47 mainLayout = QGridLayout(self) 48 mainLayout.setMargin(10) 49 mainLayout.setSpacing(10) 50 mainLayout.addLayout(self.leftLayout, 0, 0) 51 mainLayout.addLayout(self.rightLayout, 0, 1) 52 53 def LeftLayout(self): 54 self.leftLayout = QGridLayout() 55 self.leftLayout.addWidget(self.label_nickName, 0, 0) 56 self.leftLayout.addWidget(self.label_userName, 1, 0) 57 self.leftLayout.addWidget(self.label_sex, 2, 0) 58 self.leftLayout.addWidget(self.label_department, 3, 0) 59 self.leftLayout.addWidget(self.label_age, 4, 0) 60 self.leftLayout.addWidget(self.label_remark, 5, 0, 1, 2) 61 self.leftLayout.addWidget(self.lineEdit_nickName, 0, 1) 62 self.leftLayout.addWidget(self.lineEdit_userName, 1, 1) 63 self.leftLayout.addWidget(self.comboBox_sex, 2, 1) 64 self.leftLayout.addWidget(self.textEdit_department, 3, 1) 65 self.leftLayout.addWidget(self.lineEdit_age, 4, 1) 66 self.leftLayout.setColumnStretch(0, 1) 67 self.leftLayout.setColumnStretch(1, 3) 68 69 def RightLayout(self): 70 hLayout = QHBoxLayout() 71 hLayout.setSpacing(10) 72 hLayout.addWidget(self.label_icon) 73 hLayout.addWidget(self.label_picIcon) 74 hLayout.addWidget(self.btn_change) 75 self.rightLayout = QVBoxLayout() 76 self.rightLayout.setMargin(10) 77 self.rightLayout.addLayout(hLayout) 78 self.rightLayout.addWidget(self.label_desc) 79 self.rightLayout.addWidget(self.textEdit_desc) 80 81 def main(): 82 app = QApplication(sys.argv) 83 main = BaseInfo() 84 main.show() 85 app.exec_() 86 87 if __name__ == '__main__': 88 main()
JakeyContact.py:
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 import sys 5 from PyQt4.QtGui import * 6 from PyQt4.QtCore import * 7 8 class Contact(QWidget): 9 def __init__(self, parent=None): 10 super(Contact, self).__init__(parent) 11 self.CreateControls() 12 self.Layout() 13 14 def CreateControls(self): 15 self.label_email = QLabel(self.tr("Email:")) 16 self.label_contactAddress = QLabel(self.tr("Contact Address:")) 17 self.label_zipCode = QLabel(self.tr("Zip Code:")) 18 self.label_mobilePhone = QLabel(self.tr("Mobile Phone:")) 19 self.label_officePhone = QLabel(self.tr("Office Phone:")) 20 21 self.lineEdit_email = QLineEdit() 22 self.lineEdit_contactAddress = QLineEdit() 23 self.lineEdit_zipCode = QLineEdit() 24 self.lineEdit_mobilePhone = QLineEdit() 25 self.lineEdit_officePhone = QLineEdit() 26 27 def Layout(self): 28 layout = QGridLayout(self) 29 layout.addWidget(self.label_email, 0, 0) 30 layout.addWidget(self.lineEdit_email, 0, 1) 31 32 layout.addWidget(self.label_contactAddress, 1, 0) 33 layout.addWidget(self.lineEdit_contactAddress, 1, 1) 34 35 layout.addWidget(self.label_zipCode, 2, 0) 36 layout.addWidget(self.lineEdit_zipCode, 2, 1) 37 38 layout.addWidget(self.label_mobilePhone, 3, 0) 39 layout.addWidget(self.lineEdit_mobilePhone, 3, 1) 40 41 layout.addWidget(self.label_officePhone, 4, 0) 42 layout.addWidget(self.lineEdit_officePhone, 4, 1) 43 44 def main(): 45 app = QApplication(sys.argv) 46 main = Contact() 47 main.show() 48 app.exec_() 49 50 if __name__ == '__main__': 51 main()
JakeyDetail.py:
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 import sys 5 from PyQt4.QtGui import * 6 from PyQt4.QtCore import * 7 8 class Detail(QWidget): 9 def __init__(self, parent=None): 10 super(Detail, self).__init__(parent) 11 self.CreateControls() 12 self.Layout() 13 14 def CreateControls(self): 15 self.label_country = QLabel(self.tr("Country:")) 16 self.label_province = QLabel(self.tr("Province:")) 17 self.label_city = QLabel(self.tr("City:")) 18 self.label_desc = QLabel(self.tr("Personal Description:")) 19 20 self.comboBox_country = QComboBox() 21 self.comboBox_country.addItem(self.tr("Chinese")) 22 self.comboBox_country.addItem(self.tr("HK")) 23 self.comboBox_country.addItem(self.tr("TW")) 24 25 self.comboBox_province = QComboBox() 26 self.comboBox_province.addItem(self.tr("FuJian")) 27 self.comboBox_province.addItem(self.tr("HuBei")) 28 self.comboBox_province.addItem(self.tr("GuangDong")) 29 30 self.lineEdit_city = QLineEdit() 31 self.textEdit_desc = QTextEdit() 32 33 def Layout(self): 34 layout = QGridLayout(self) 35 layout.addWidget(self.label_country, 0, 0) 36 layout.addWidget(self.comboBox_country, 0, 1) 37 38 layout.addWidget(self.label_province, 1, 0) 39 layout.addWidget(self.comboBox_province, 1, 1) 40 41 layout.addWidget(self.label_city, 2, 0) 42 layout.addWidget(self.lineEdit_city, 2, 1) 43 44 layout.addWidget(self.label_desc, 3, 0) 45 layout.addWidget(self.textEdit_desc, 3, 1) 46 47 def main(): 48 app = QApplication(sys.argv) 49 main = Detail() 50 main.show() 51 app.exec_() 52 53 if __name__ == '__main__': 54 main()
本实例综合应用了各种布局方式,完成一个较为复杂的界面显示。包括了各种基本布局类的应用,堆栈窗的应
用和分割窗的应用。
要达到同样的显示效果,会有多种可能的布局方案,在实际应用中,应根据具体情况进行选择,使用最方便合
理的布局方式。一般来说,QGridLayout 功能较为强大,能完成 QHBoxLayout 与 QVBoxLayout 的功能,
但视具体情况,若只是简单的控件水平或竖直排列,使用 QHBoxLayout 和 QVBoxLayout 更加方
便,QGridLayout 适合较为整齐方正的界面布局。

浙公网安备 33010602011771号