目录
一、按钮
pyqt的按钮都是继承自QAbstractButton,所以它们在很多地方都是有共同特性的。
1、QPushButton
QPushButton:最常用的按钮,点击之后执行一个命令或操作。
QPushButton最常用的信号是clicked,还有不常用的信号:pressed和released。
QPushButton在对话框(QDialog)中默认为auto-default按钮,在其它窗体中可以通过setAutoDefault()设置为auto-default按钮,auto-default按钮有两点特殊:
①获得焦点时可以响应键盘的Enter按键
②获得焦点时有一个粗线的边框
示例:
class ButtonWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('测试button')
self.resize(800, 600)
self.main_layout = QHBoxLayout()
self.pb1 = QPushButton("点击")
self.pb1.setIcon(QIcon('icons/home.png'))
self.pb1.clicked.connect(partial(self.click_test, "点击一下"))
self.main_layout.addWidget(self.pb1)
self.pb2 = QPushButton("再次点击")
self.pb2.clicked.connect(partial(self.click_test, "再次点击"))
self.main_layout.addWidget(self.pb2)
self.pb3 = QPushButton("还点击")
self.pb3.clicked.connect(partial(self.click_test, "还点击"))
self.pb3.setAutoDefault(True)
self.main_layout.addWidget(self.pb3)
self.setLayout(self.main_layout)
@classmethod
def click_test(cls, s):
print(s)
2、QRadioButton
单选按钮,通常的用法是提供一组单选按钮,每次只能选中一个。
QRadioButton的互斥选中是通过auto-exclusive来控制的,QRadioButton的auto-exclusive默认都是True,可以通过setAutoExclusive()来设置。
QRadioButton状态切换时会发出toggled信号
同一个widget下的所有QRadioButton默认是处于同一个互斥组,如果要分成多个互斥组,则需要使用QButtonGroup包裹。
class ButtonWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('测试button')
self.resize(800, 600)
# 本窗口下的QRadioButton分成三个互斥组,互不影响
self.main_layout = QVBoxLayout()
self.l_1 = QHBoxLayout()
self.l_1.addWidget(QLabel("性别:"))
# 性别是一个互斥组
self.group_sex = QButtonGroup()
self.rb_male = QRadioButton('男')
self.l_1.addWidget(self.rb_male)
self.rb_female = QRadioButton('女')
self.l_1.addWidget(self.rb_female)
self.group_sex.addButton(self.rb_male)
self.group_sex.addButton(self.rb_female)
self.main_layout.addLayout(self.l_1)
self.l_2 = QHBoxLayout()
self.l_2.addWidget(QLabel("工作地址:"))
# 工作地址是一个互斥组
self.group_address = QButtonGroup()
self.rb_shanghai = QRadioButton('上海')
self.l_2.addWidget(self.rb_shanghai)
self.rb_beijing = QRadioButton('北京')
self.l_2.addWidget(self.rb_beijing)
self.rb_shenzhen = QRadioButton('深圳')
self.l_2.addWidget(self.rb_shenzhen)
self.group_address.addButton(self.rb_shanghai)
self.group_address.addButton(self.rb_beijing)
self.group_address.addButton(self.rb_shenzhen)
self.main_layout.addLayout(self.l_2)
self.l_3 = QHBoxLayout()
# 学历没有使用QButtonGroup,因为都是位于同一个主窗口之下,所以成为一个互斥组
self.l_3.addWidget(QLabel("学历:"))
self.rb_gz = QRadioButton('高中')
self.l_3.addWidget(self.rb_gz)
self.rb_bk = QRadioButton('本科')
self.l_3.addWidget(self.rb_bk)
self.rb_ss = QRadioButton('硕士')
self.l_3.addWidget(self.rb_ss)
self.rb_bs = QRadioButton('博士')
self.rb_bs.toggled.connect(self.test1)
self.l_3.addWidget(self.rb_bs)
self.main_layout.addLayout(self.l_3)
self.setLayout(self.main_layout)
@classmethod
def test1(cls, status):
# status为bool,代表当前是否选中
print(status)
3、QCheckBox
复选框。通常用于在不影响其他功能的情况下开启或禁用某项功能。
QCheckBox默认是不互斥的,要实现互斥效果则需要用QButtonGroup包裹。
QCheckBox状态改变时会发出stateChanged信号
QCheckBox默认有两个状态:选中(2)、未选中(0),通过setTristate(True)可以开启第三个状态:
无改变(1)
class ButtonWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('测试button')
self.resize(800, 600)
self.main_layout = QVBoxLayout()
self.l_1 = QHBoxLayout()
self.l_1.addWidget(QLabel('爱好'))
# cb1和cb2使用QButtonGroup包裹了,所以它们互斥了,即同时只有一个能选中
self.group1 = QButtonGroup()
self.cb1 = QCheckBox('游泳')
self.cb1.setIcon(QIcon('icons/home.png'))
self.cb2 = QCheckBox('跑步')
self.group1.addButton(self.cb1)
self.group1.addButton(self.cb2)
self.cb3 = QCheckBox('读书')
# cb3开始无改变状态
self.cb3.setTristate(True)
# 监听cb3的状态改变信号
self.cb3.stateChanged.connect(self.test1)
self.l_1.addWidget(self.cb1)
self.l_1.addWidget(self.cb2)
self.l_1.addWidget(self.cb3)
self.main_layout.addLayout(self.l_1)
self.setLayout(self.main_layout)
@classmethod
def test1(cls, status):
# status为整数值,分别代表QCheckBox当前的状态
print(status)
4、QToolButton
QToolButton并不是一个独立使用的按钮,而是QToolBar专用,详情参加:QToolBar说明。
5、QCommandLinkButton
这个按钮用的不多,详细的可以参见官网文档:QCommandLinkButton详情。
二、显示类控件
显示类控件主要用于向用户展示数据,它们没有用户交互功能。
1、QLabel
标签是最常用的显示控件,可以显示的数据如下:
Content | Setting |
---|---|
纯文本 | 通过setText()设置 |
富文本 | 通过setText()设置包含富文本的文本 |
图片 | 通过setPixmap()设置 |
gif动图 | 通过setMovie()设置 |
数字 | 通过setNum()设置 |
class DisplayWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('显示类控件')
self.setFixedSize(800, 600)
self.main_layout = QVBoxLayout()
self.label1 = QLabel()
# 显示一个数字
self.label1.setNum(123.123)
self.label2 = QLabel()
# 显示一个QString
self.label2.setText('这是一个标签')
self.label3 = QLabel()
# 显示一个gif
self.movie = QMovie("medias/test1.gif")
self.label3.setMovie(self.movie)
self.movie.start()
self.label4 = QLabel()
# 显示一个图片
self.label4.setPixmap(QPixmap('icons/home.png'))
self.main_layout.addWidget(self.label1)
self.main_layout.addWidget(self.label2)
self.main_layout.addWidget(self.label3)
self.main_layout.addWidget(self.label4)
self.setLayout(self.main_layout)
2、QTextBrowser
QTextBrowser类提供了一个具有超文本导航功能的富文本浏览器。
想了解的可以看官网文档:QTextBrowser说明。
3、QCalendarWidget
QCalendarWidget类提供了一个基于月的日历widget,允许用户选择日期。
QCalendarWidget有很多可以设置的地方,具体参考官网文档:QCalendarWidget说明。
class DisplayWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('显示类控件')
self.resize(800, 600)
self.main_layout = QVBoxLayout()
self.calendar = QCalendarWidget()
self.main_layout.addWidget(self.calendar)
self.setLayout(self.main_layout)
4、QLCDNumber
QLCDNumber显示具有类似LCD数字样式的数字:QLCDNumber说明。
5、QProgressBar
QProgressBar提供一个水平或垂直的进度条。
进度百分比的计算方法是:(value()-minimum()) / (maximum()-minimum())。
使用setMinimum()和setMaximum()指定最小和最大值。当前值是用setValue()设置的。进度条可以用reset()重新滚动到开头。
如果最小值和最大值都设置为0,则QProgressBar将显示当前忙样式的指示器,这对不确定进度的情况很有用:
更多用法参见官网文档:QProgressBar说明
下面是一个使用进度条指示下载进度的示例:
class DisplayWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('显示类控件')
self.resize(400, 100)
self.main_layout = QVBoxLayout()
self.btn = QPushButton("开始下载")
# 开始下载
self.btn.clicked.connect(self.start_download)
self.btn1 = QPushButton("取消下载")
# 取消下载
self.btn1.clicked.connect(self.pause_download)
# 使用一个定时器模拟下载过程
self.timer = QTimer()
self.timer.timeout.connect(self.update_progress)
self.c_layout = QHBoxLayout()
self.c_layout.addWidget(QLabel("下载状态:"))
# 指示下载进度的进度条
self.pbar = QProgressBar()
self.pbar.setMaximum(100)
self.pbar.setMinimum(0)
self.pbar.setValue(0)
self.c_layout.addWidget(self.pbar)
self.main_layout.addWidget(self.btn)
self.main_layout.addWidget(self.btn1)
self.main_layout.addLayout(self.c_layout)
self.setLayout(self.main_layout)
def start_download(self):
# 启动定时器
self.timer.start(1000)
def pause_download(self):
# 停止定时器
self.timer.stop()
def update_progress(self):
if self.pbar.value() == self.pbar.maximum():
# 下载完成,停止定时器
print('download success')
self.timer.stop()
# 更新下载进度
self.pbar.setValue(self.pbar.value()+1)
效果图:
6、QFrame
这里只说下用QFrame创建没有任何内容的简单占位符框架。
框架样式由框架形状和阴影样式指定,阴影样式用于在视觉上将框架与周围的widgets分离。这些属性可以使用setFrameStyle()函数一起设置,并使用frameStyle()读取。形状和样式见下表:
例如实现一个水平分隔线:
class DisplayWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('显示类控件')
self.resize(400, 100)
self.main_layout = QVBoxLayout()
self.line1 = QFrame()
self.line1.setFrameShape(QFrame.HLine)
self.line1.setFrameShadow(QFrame.Sunken)
self.main_layout.addWidget(self.line1)
self.setLayout(self.main_layout)