目录
按钮控件(QpushButton)
单选按钮控件QRatioButton
复选框控件QCheckBox
下拉列表控件ComboBox
滑块控件QSlider
滑块步长和间隔的区别
计数器控件QSpinBox
QAbstractButton(所有按钮控件的父类)
QPushButton(普通按钮)
AToolButton(工具条按钮)
QRadioButton(单选框按钮)
QCheckBox(复选框按钮)
代码:
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class QPushButtonDemo(QDialog):
def __init__(self):
super(QPushButtonDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QPushButton Demo')
self.resize(350,200)
layout=QVBoxLayout() #垂直布局
self.btn1=QPushButton('第一个按钮')
self.btn1.setText('First Button1')
#下面两句配合使用,功能类似于单选框按钮QCheckBox
self.btn1.setCheckable(True)
self.btn1.toggle() #按一下就按下去了,再按一下才能抬起
#btn1一个信号对应两个槽函数
self.btn1.clicked.connect(self.buttonState) #先绑定谁系统就先调用谁
self.btn1.clicked.connect(lambda :self.whichButton(self.btn1))
layout.addWidget(self.btn1)
#在文本前面显示图像
self.btn2=QPushButton('图像按钮')
self.btn2.setIcon(QIcon(QPixmap('casually input')))
self.btn2.clicked.connect(lambda :self.whichButton(self.btn2))
layout.addWidget(self.btn2)
self.btn3=QPushButton('不可用的按钮')
self.btn3.setEnabled(False)
layout.addWidget(self.btn3)
self.btn4=QPushButton('&MyButton') #设置了热键M/m
self.btn4.setDefault(True) #如果没有任何按钮被选中,那么按回车就是按了这个按钮
self.btn4.clicked.connect(lambda :self.whichButton(self.btn4))
layout.addWidget(self.btn4)
self.setLayout(layout)
'''
注意下面的方法是两个参数,如果用传统的信号与槽连接方式的话,只会将按钮对象本身传入,那样的话第二个参数就没有传入值了
所以要用lambda表达式,当前对象直接调用这个函数,传入的值就对应第二个参数了
'''
def whichButton(self,btn):
#self.sender() #通过此方法可得到是哪个按钮被按下,或者可用此方法中的传参方法
print('被单击的按钮是<'+btn.text()+'>')
def buttonState(self):
if self.btn1.isChecked():
print('按钮1已经被选中')
else:
print('按钮1未被选中')
if __name__=='__main__':
app=QApplication(sys.argv)
main=QPushButtonDemo()
main.show()
sys.exit(app.exec_())
运行结果:
开始啥都不要选,先按一个一个回车,果然按钮4反应了,然后连按两下按钮1,再用热键Alt+m,再点按钮2,按钮3点不了。
在一个容器内的单选按钮是互斥的,即选中了一个单选按钮,就不能再选中另一个单选按钮,也就是不能同时处于选中状态。在不同容器中的单选按钮是分开的,互不影响。
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class QRatioButtonDemo(QWidget):
def __init__(self):
super(QRatioButtonDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QRatioButton')
self.resize(350,100)
#水平布局
layout=QHBoxLayout()
self.btn1=QRadioButton('单选按钮1')
# 设为默认是选中状态
self.btn1.setChecked(True)
#toggled是状态切换的信号
self.btn1.toggled.connect(self.buttonState)
layout.addWidget(self.btn1)
self.btn2=QRadioButton('单选按钮2')
self.btn2.toggled.connect(self.buttonState)
layout.addWidget(self.btn2)
self.setLayout(layout)
def buttonState(self):
ratiobtn=self.sender()
if ratiobtn.isChecked() == True:
print('<' + ratiobtn.text() + '>被选中')
else:
print('<' + ratiobtn.text() + '>被取消选中状态')
#同意容器下单选按钮是互斥的,所以不必利用ratiobtn.text()来分情况判断
'''
if ratiobtn.text()=='单选按钮1':
#是否被选中
if ratiobtn.isChecked()==True:
print('<'+ratiobtn.text()+'>被选中')
else:
print('<'+ratiobtn.text()+'>被取消选中状态')
if ratiobtn.text()=='单选按钮2':
if ratiobtn.isChecked()==True:
print('<'+ratiobtn.text()+'>被选中')
else:
print('<'+ratiobtn.text()+'>被取消选中状态')
'''
if __name__=='__main__':
app=QApplication(sys.argv)
main=QRatioButtonDemo()
main.show()
sys.exit(app.exec_())
运行结果:
3种状态:
未选中:0
半选中:1
选中:2
tristate属性表示复选框是三种状态还是两种状态,如果tristate为true,则表示复选框中有选中,半选中,未选中三种状态,即setTristate(True)即表示允许半选中。
self.checkbox3.setCheckState(Qt.PartiallyChecked)可设置的三种状态
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtCore import Qt #其中有许多常量
class QCheckBoxDemo(QWidget):
def __init__(self):
super(QCheckBoxDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QCheckBoxDemo')
self.resize(350,100)
layout=QHBoxLayout()
self.checkbox1=QCheckBox('复选框控件1')
#默认选中
self.checkbox1.setChecked(True)#此函数只有两种状态
self.checkbox1.stateChanged.connect(lambda :self.checkboxState(self.checkbox1))
layout.addWidget(self.checkbox1)
self.checkbox2=QCheckBox('复选框控件2')
self.checkbox2.stateChanged.connect(lambda: self.checkboxState(self.checkbox2))
layout.addWidget(self.checkbox2)
self.checkbox3=QCheckBox('半选中控件3')
#设置选中有三个状态(即允许半选中)
self.checkbox3.setTristate(True)
#setCheckState函数有三种状态:Unchecked,PartiallyChecked,Checked
self.checkbox3.setCheckState(Qt.PartiallyChecked)
self.checkbox3.stateChanged.connect(lambda: self.checkboxState(self.checkbox3))
layout.addWidget(self.checkbox3)
self.setLayout(layout)
def checkboxState(self,cb):
check1Status=self.checkbox1.text()+',isChecked='+str(self.checkbox1.isChecked())+',isCheckstate='+str(self.checkbox1.checkState())+'\n'
check2Status=self.checkbox2.text() + ',isChecked=' + str(self.checkbox2.isChecked()) + ',isCheckstate' + str(self.checkbox2.checkState()) + '\n'
check3Status=self.checkbox3.text() + ',isChecked=' + str(self.checkbox3.isChecked()) + ',isCheckstate' + str(self.checkbox3.checkState()) + '\n'
print(check1Status+check2Status+check3Status)
if __name__=='__main__':
app=QApplication(sys.argv)
main=QCheckBoxDemo()
main.show()
sys.exit(app.exec_())
运行结果:
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtCore import Qt #其中有许多常量
class QComboBoxDemo(QWidget):
def __init__(self):
super(QComboBoxDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QComboBoxDemo')
self.resize(350,100)
#垂直布局
layout=QVBoxLayout()
self.label=QLabel('请选择编程语言')
self.cb=QComboBox()
self.cb.addItem('C++')
self.cb.addItem('Python')
self.cb.addItems(['Java','C#','Ruby'])
#每一项都对应一个下标索引
self.cb.currentIndexChanged.connect(self.selectionChange)#此信号默认传递两个参数(控件本身,索引)
layout.addWidget(self.label)
layout.addWidget(self.cb)
self.setLayout(layout)
def selectionChange(self,i):
#标签会随着当前选中的下拉项而改变
self.label.setText(self.cb.currentText())
self.label.adjustSize()
for j in range(self.cb.count()):
print('item'+str(j)+'='+self.cb.itemText(j))
print('current index',i,'selection changed',self.cb.currentText())
if __name__=='__main__':
app=QApplication(sys.argv)
main=QComboBoxDemo()
main.show()
sys.exit(app.exec_())
运行结果:
bug:
TypeError: __init__() takes 1 positional argument but 2 were given
我把类名直接命名成QSlider了。。。关于函数类这一块的基础知识有点忘了
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import Qt #其中有许多常量
class QSliderDemo(QWidget):
def __init__(self):
super(QSliderDemo,self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('QSliderDemo')
self.resize(350,500)
#垂直布局
layout=QVBoxLayout()
self.label=QLabel('Hello PyQt5!')
self.label.setAlignment(Qt.AlignCenter)
layout.addWidget(self.label)
#滑块分为水平和垂直两种
#水平slider1
self.slider1=QSlider(Qt.Horizontal)#水平,左右滑动
#设置最小值
self.slider1.setMinimum(12)
# 设置最大值
self.slider1.setMaximum(48)
#步长
self.slider1.setSingleStep(3)
#设置当前值
self.slider1.setValue(18)
#设置刻度的位置,刻度在下方
self.slider1.setTickPosition(QSlider.TicksBelow)
#刻度间隔
self.slider1.setTickInterval(6)
self.slider1.valueChanged.connect(self.valueChange)
#垂直slider2
self.slider2=QSlider(Qt.Vertical) #垂直滑块
self.slider2.setMinimum(1)
self.slider2.setMaximum(80)
self.slider2.setSingleStep(5)
self.slider2.setTickPosition(QSlider.TicksLeft)#刻度条放在滑块的左边
self.slider2.setTickInterval(10)
self.slider2.valueChanged.connect(self.valueChange)
layout.addWidget(self.slider1)
layout.addWidget(self.slider2)
self.setLayout(layout)
def valueChange(self):
'''
注意这里是sender(),而不是slider1也不是slider2,sender()获取当前操作的控件,
这样无论拖动哪个滑动条字体大小都会变化,因为这俩信号对应这一个槽函数
'''
print('当前值:%s'% self.sender().value())
size=self.sender().value() #获得当前值
#使字号根据当前值来变化
self.label.setFont(QFont('Arial',size))
if __name__=='__main__':
app=QApplication(sys.argv)
main=QSliderDemo()
main.show()
sys.exit(app.exec_())
运行结果:
间隔就是刻度点的间隔,比如slider1刻度范围是12-48,刻度间隔是6,所以有(48-12)/6=6个间隔,即7个刻度点
而对于步长,你先用鼠标选中上图中的任一个滑动条,然后用上下(或左右)键调节,每次调节的大小就是步长。
代码:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import Qt #其中有许多常量
class QSpinBoxDemo(QWidget):
def __init__(self):
super(QSpinBoxDemo,self).__init__()
self.initUI()
def initUI(self):
####################################### 窗口设置
self.setWindowTitle('QSliderDemo')
self.resize(350,120)
#垂直布局
layout=QVBoxLayout()
######################################## 控件
self.label=QLabel('当前值')
self.label.setAlignment(Qt.AlignCenter)
self.sb=QSpinBox()
#默认值
self.sb.setValue(18)
#设置范围
self.sb.setRange(10,38)
#设置步长
self.sb.setSingleStep(3)
####################################### 信号与槽
self.sb.valueChanged.connect(self.valueChange)
####################################### 组装
layout.addWidget(self.label)
layout.addWidget(self.sb)
self.setLayout(layout)
def valueChange(self):
self.label.setText('当前值:'+str(self.sb.value()))
if __name__=='__main__':
app=QApplication(sys.argv)
main=QSpinBoxDemo()
main.show()
sys.exit(app.exec_())
运行结果: