15.1 QGroupBox
15.2 QToolBox
15.3 小结
就跟分类一样,我们可以把相同的控件放在一起,也可以把达到某项功能所需要的一些控件放在一起等等,合理运用这两个控件可以让界面更加清晰,用户体验度更好。
我们来升级一下在第七章制作的开关灯泡小程序,完成后截图如下:
可以看出在这个程序中,左边的QGroupBox放着On和Off按钮,而右边的QGrouoBox则放着各种颜色按钮。该程序不仅可以开关灯泡,还可以改变灯泡的颜色,代码如下:
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QWidget, QGroupBox, QRadioButton, QLabel, QHBoxLayout, QVBoxLayout
class Demo(QWidget):
def __init__(self):
super(Demo, self).__init__()
self.groupbox_1 = QGroupBox('On and Off', self) # 1
self.groupbox_2 = QGroupBox('Change Color', self)
self.red = QRadioButton('Red', self) # 2
self.blue = QRadioButton('Blue', self)
self.green = QRadioButton('Green', self)
self.yellow = QRadioButton('Yellow', self)
self.color_list = [self.red, self.blue, self.green, self.yellow]
self.on = QRadioButton('On', self) # 3
self.off = QRadioButton('Off', self)
self.pic_label = QLabel(self) # 4
self.h1_layout = QHBoxLayout()
self.h2_layout = QHBoxLayout()
self.h3_layout = QHBoxLayout()
self.all_v_layout = QVBoxLayout()
self.layout_init()
self.radiobutton_init()
self.label_init()
def layout_init(self):
self.h1_layout.addWidget(self.on)
self.h1_layout.addWidget(self.off)
self.groupbox_1.setLayout(self.h1_layout)
self.h2_layout.addWidget(self.red)
self.h2_layout.addWidget(self.blue)
self.h2_layout.addWidget(self.green)
self.h2_layout.addWidget(self.yellow)
self.groupbox_2.setLayout(self.h2_layout)
self.h3_layout.addWidget(self.groupbox_1)
self.h3_layout.addWidget(self.groupbox_2)
self.all_v_layout.addWidget(self.pic_label)
self.all_v_layout.addLayout(self.h3_layout)
self.setLayout(self.all_v_layout)
def radiobutton_init(self):
self.yellow.setChecked(True) # 5
for btn in self.color_list:
btn.clicked.connect(self.change_color_func)
self.off.setChecked(True) # 6
self.off.toggled.connect(self.on_and_off_func)
def label_init(self): # 7
self.pic_label.setPixmap(QPixmap('images/Off.png'))
self.pic_label.setAlignment(Qt.AlignCenter)
def change_color_func(self):
if self.on.isChecked():
path = 'images/{}.png'.format([btn.text() for btn in self.color_list if btn.isChecked()][0])
self.pic_label.setPixmap(QPixmap(path))
def on_and_off_func(self):
if self.on.isChecked():
path = 'images/{}.png'.format([btn.text() for btn in self.color_list if btn.isChecked()][0])
self.pic_label.setPixmap(QPixmap(path))
else:
self.pic_label.setPixmap(QPixmap('images/Off.png'))
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Demo()
demo.show()
sys.exit(app.exec_())
1. 实例化两个QGroupBox组合框,第一个用来放置On和Off单选按钮,第二个用来放置各种颜色按钮;
2. 实例化各个颜色按钮,并将它们放在一个列表中,方便之后使用列表推导式来简化代码;
3. 实例化On和Off单选按钮;
4. 实例化一个QLabel控件,用于显示图片;
5. 在radiobutton_init()函数中,我们先将yellow单选按钮设置为已点击状态,然后用各个颜色按钮的clicked信号与自定义的槽函数change_color_func()连接起来。
在下面这个槽函数中,我们先判断On单选按钮是否是已点击状态(因为如果电源没开的话,灯泡颜色是不会变化的) ,如果是的话则获取图片路径path,然后将QLabel设为相应的图片,这里我们详细分析下。
def change_color_func(self):
if self.on.isChecked():
path = 'images/{}.png'.format([btn.text() for btn in self.color_list if btn.isChecked()][0])
self.pic_label.setPixmap(QPixmap(path))
首先以下列表推导式循环判断是哪一个颜色按钮处于点击状态,然后将该按钮的显示文本获取过来。
[btn.text() for btn in self.color_list if btn.isChecked()][0]
接着将相应的颜色放进字符串中 ,比如Red单选按钮处于点击状态,则path为'images/Red.png'。
path = 'images/{}.png'.format([btn.text() for btn in self.color_list if btn.isChecked()][0]
最后将QLabel设为相应的颜色:
self.pic_label.setPixmap(QPixmap(path))
6. 将Off按钮设为点击状态,然后将它的toggled信号与自定义的槽函数连接起来(槽函数原理与5中类似,不再讲解);
7. 将刚开始显示的QLabel图片设置为Off.png,然后让其居中显示。
图片下载地址(注意因为路径为'images/xxx.png,所以这些图片都要放在项目中的images文件夹下):
运行截图如下,点击On按钮灯泡亮起:
点击其他按钮换种颜色:
如果刚开始处于Off状态,我们想一开始显示的就是红色灯泡,则先选中Red,然后再点击On:
我们发现左边的On和Off单选按钮与右边的各颜色按钮互不影响(单选按钮就是每次只能有一个按钮被选中),这就是QGroupBox带来的效果,左右两边各司其职。
QToolBox工具箱,这个工具箱有很多抽屉,每次只能打开一个,抽屉里可以放很各种各样的东西。我们知道QQ上有很多分组,然后每个分组下可以放很多联系人:
点开我的好友分组,该分组下放着相应的联系人:
我们现在用QToolBox工具来实现类似样式,代码如下:
import sys
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QToolBox, QGroupBox, QToolButton, QVBoxLayout
class Demo(QToolBox): # 1
def __init__(self):
super(Demo, self).__init__()
self.groupbox_1 = QGroupBox(self) # 2
self.groupbox_2 = QGroupBox(self)
self.groupbox_3 = QGroupBox(self)
self.toolbtn_f1 = QToolButton(self) # 3
self.toolbtn_f2 = QToolButton(self)
self.toolbtn_f3 = QToolButton(self)
self.toolbtn_m1 = QToolButton(self)
self.toolbtn_m2 = QToolButton(self)
self.toolbtn_m3 = QToolButton(self)
self.v1_layout = QVBoxLayout()
self.v2_layout = QVBoxLayout()
self.v3_layout = QVBoxLayout()
self.addItem(self.groupbox_1, 'Couple One') # 4
self.addItem(self.groupbox_2, 'Couple Two')
self.addItem(self.groupbox_3, 'Couple Three')
self.currentChanged.connect(self.print_index_func) # 5
self.layout_init()
self.groupbox_init()
self.toolbtn_init()
def layout_init(self):
self.v1_layout.addWidget(self.toolbtn_f1)
self.v1_layout.addWidget(self.toolbtn_m1)
self.v2_layout.addWidget(self.toolbtn_f2)
self.v2_layout.addWidget(self.toolbtn_m2)
self.v3_layout.addWidget(self.toolbtn_f3)
self.v3_layout.addWidget(self.toolbtn_m3)
def groupbox_init(self): # 6
self.groupbox_1.setFlat(True)
self.groupbox_2.setFlat(True)
self.groupbox_3.setFlat(True)
self.groupbox_1.setLayout(self.v1_layout)
self.groupbox_2.setLayout(self.v2_layout)
self.groupbox_3.setLayout(self.v3_layout)
def toolbtn_init(self): # 7
self.toolbtn_f1.setIcon(QIcon('images/f1.ico'))
self.toolbtn_f2.setIcon(QIcon('images/f2.ico'))
self.toolbtn_f3.setIcon(QIcon('images/f3.ico'))
self.toolbtn_m1.setIcon(QIcon('images/m1.ico'))
self.toolbtn_m2.setIcon(QIcon('images/m2.ico'))
self.toolbtn_m3.setIcon(QIcon('images/m3.ico'))
def print_index_func(self):
couple_dict = {
0: 'Couple One',
1: 'Couple Two',
2: 'Couple Three'
}
sentence = 'You are looking at {}.'.format(couple_dict.get(self.currentIndex()))
print(sentence)
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Demo()
demo.show()
sys.exit(app.exec_())
1. 因为要显示的最终控件也就是QToolBox,所以这里就直接继承QToolBox;
2. 实例化三个QGroupBox控件,目的是将6个头像分别放入这三个QGroupBox中;
3. QToolButton用于显示头像;
4. 通过addItem(QWidget, Str)方法将QGroupBox添加到QToolBox中,第一个参数为要添加的控件,第二个参数是给每个QToolBox抽屉设定的名称;
5. 每当用户点击不同抽屉时,都会触发currentChanged信号,我们将该信号连接到自定义的槽函数上:
def print_index_func(self):
couple_dict = {
0: 'Couple One',
1: 'Couple Two',
2: 'Couple Three'
}
sentence = 'You are looking at {}.'.format(couple_dict.get(self.currentIndex()))
print(sentence)
通过currentIndex()方法可以获取到当前所点击的抽屉序号,序号从0开始。这里通过字典来获取相应的抽屉名称,然后将其打印出来;
6. setFlat(True)方法可以让QGroupBox的边框消失;
7. 通过setIcon(QIcon)方法来设置QToolButton的图标;
图片下载(注意因为路径为'images/xxx.png,所以这些图片都要放在项目中的images文件夹下):
运行截图如下:
每次点击不同的抽屉,控制台都会输出相应的抽屉名:
1. QGroupBox组合框和QToolBox工具箱可以很好的用来将界面各部分控件进行归类,让界面更加友好,从而提高用户体验度;
2. 不同QGroupBox中的单选按钮QRadioButton互不影响;
3. QToolBox可以用addItem(QWidget, Str)方法来添加抽屉,每一个抽屉都是一个控件。当用户点击不同抽屉时,会触发currentChanged信号。
----------------------------------------------------------------------
喜欢的小伙伴可以加入这个Python QQ交流群一起学习:820934083