【转】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 适合较为整齐方正的界面布局。

posted @ 2014-11-18 17:09  jakey.chen  阅读(733)  评论(0)    收藏  举报