'''
学习文档:
直接查看Qt文档:https://doc.qt.io/
很全的文档:http://www.kuqin.com/qtdocument/classes.html
知乎pyq5介绍:https://mp.youkuaiyun.com/postedit
https://fishc.com.cn/forum.php?mod=viewthread&tid=59816&extra=page%3D1&page=1
学习网站:https://maicss.gitbooks.io/pyqt5/content/hello_world.html
https://www.jianshu.com/p/362ff61a96b6
http://code.py40.com/1948.html
推荐博客:https://blog.youkuaiyun.com/jia666666/article/category/7916211 这个总结详细
https://blog.youkuaiyun.com/baidu_34045013/article/details/52132308
https://www.cnblogs.com/ygzhaof/p/10071428.html
州的先生博客:https://zmister.com/archives/category/guidevelop/pyqt5_basic/
码农网:https://www.codercto.com/a/19041.html
视频:https://www.bilibili.com/video/av54310770
'''
模块:
pyqt5主要的几个模块介绍:
首先举个例子:导入模块 from PyQt5.QtWidgets import Qwidget,QApplication
(1)QtCore:包含核心的非GUI功能,用于处理时间,文件和目录,各种数据类型,流,URL,MIME类型,线程或进程
(2)QtGui:包含类窗口系统集成,事件处理,二维图形,基本成像,字体和文本
(3)Qtwidgets:包含创造经典桌面风格的用户界面提供一套UI元素的类
(4)QtMultimedia:包含类来处理多媒体内容和Api来访问相机和收音机
(5)Qtbluetooth:包含类的扫描设备和连接并与他们互动,描述模块包含了网络编程的类。这些类便于TCP和IP和UDP客户端和服务器的编码,使网络编程更容易和更便携。
(6)Qtpositioning : 包含类的利用各种可能的来源,确定位置,包括卫星,wifi或一个文本文件
(7)QtSql:提供操作数据库的类
(8)Enginio模块实现了客户端库访问Qt云服务托管的应用程序运行时。
(9)Qtwebsockets模块包含实现WebSocket协议类。
(10)QtWebKit包含一个基于Webkit2图书馆Web浏览器实现类。
(11)Qtwebkitwidgets包含的类的基础webkit1一用于qtwidgets应用Web浏览器的实现。
(12)QtXml包含与XML文件的类。这个模块为SAX和DOM API提供了实现。
(13)QtSvg模块提供了显示SVG文件内容的类。可伸缩矢量图形(SVG)是一种描述二维图形和图形应用的语言。
(14)QtTest:使pyqt5应用程序的单元测试
流程:qtdesigner设计界面保存为.ui文件----> 使用命令pyuic5 -o demo.py demo.ui 将ui文件转为py文件 ----->调用生成的py文件
调用的方法如下:
import sys
from PyQt5.Qtwidgets import QMainWindow,QApplication
from demo import Ui_MainWindow
if __name__='__main__':
app=QApplication(sys.argv)
mainwindow=QMainWindowt()
mainwindow.setWindowTitle('Qdesigner demo')
#调用生成的demo.py文件类Ui_MainWindow里的setupUi()方法
new=Ui_MainWindow()
new.setupUi(mainwindow)
widget.show()
sys.exit(app.exec_())
(1)pyqt5布局:水平布局,垂直布局,栅格布局,表单布局,绝对布局
(2)尺寸策略(sizePolicy):
隐藏尺寸(sizeHint):相当于默认的控件的尺寸,对于大多数sizeHint的值只是可读的
例如读取pushbutton的sizeHint值:self.pushButton.sizeHint().width() self.pushButton.sizeHint().height()
(3)事件与信号
所有的GUI程序都是事件驱动的。事件主要由用户触发,但也可能有其他触发方式:例如网络连接,window manager或定时器。当我们调用QApplication的exec_()方法时会使程序进入主循环,主循环会获取并发事件
在事件模型中有三个参与者:---事件源 -----事件(对象)------事件接受者
PyQt5有一个独特的signal&slot(信号槽)机制来处理事件。信号槽用于对象间的通信。signal在某一特定事件发生时被触发,slot可以是任何callable对象。当signal触发时会调用与之相连的slot。
例如简单的例子
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QWidget, QLCDNumber, QSlider, QVBoxLayout, QApplication)
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
lcd = QLCDNumber(self)
sld = QSlider(Qt.Horizontal, self)
vbox = QVBoxLayout()
vbox.addWidget(lcd)
vbox.addWidget(sld)
self.setLayout(vbox)
sld.valueChanged.connect(lcd.display)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle("Signal & slott")
self.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
通过QObject创建的对象可以发出信号。下面的示例演示了如何发出自定义信号
import sys
from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtWidgets import QMainWindow, QApplication
class Communicate(QObject):
closeApp = pyqtSignal()
class Example(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.c = Communicate()
self.c.closeApp.connect(self.close)
self.setGeometry(300, 300, 290, 150)
self.setWindowTitle("Emit signal")
self.show()
def mousePressEvent(self, event):
self.c.closeApp.emit()
if __name__ == "__main__":
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
(4)设置伙伴关系(buddy)设置buddy关系时,设置其中一个控件的可快速定位至其伙伴关系控件。主要应用在label与edit控件之间,便于快速切换编辑
例子:
self.setGeometry(300,300,300,200)
self.setWindowTitle("buddy")
grid=QGridLayout()
self.setLayout(grid)
#设置label和linedit 用&大写字母,相当于快捷键ALT+大写字母,setBuddy()方法建立兄弟关系
label1=QLabel('&Name')
grid.addWidget(label1,0,0)
edit1=QLineEdit()
grid.addWidget(edit1,0,1)
label1.setBuddy(edit1)
label2=QLabel('&Email')
grid.addWidget(label2,1,0)
edit2=QLineEdit()
grid.addWidget(edit2,1,1)
label2.setBuddy(edit2)
self.show()
(5)信号槽(signal&slot) 是Pyqt的核心机制
信号(signal):是由对象或控件发射出来的消息 例如:单击按钮时,按钮就会向外部发送单击的消息
槽(slot):发送出的信息需要代码来拦截,进行处理(相当于处理事件)
(6)三种栏:菜单栏,工具栏,状态栏
(7)3种窗口:QMainWindow,QWidget,QDialog (详见另一篇文章)
QMainWindow:是最常用的,包含菜单栏,工具栏,状态栏和标题栏
QDialog:弹出框基类,没有菜单栏,工具栏,状态栏
QWidget:不确定窗口的用途,就用QWidget
控件被改变
(8)获取窗口的坐标系和长宽
#第一种方式(mac下包含标题栏的长宽)
#获取窗口相对于屏幕的坐标(包含标题)
print('x坐标:'+str(self.x())+'y坐标'+str(self.y()))
#获取窗口的长度和宽度
print('宽度'+str(self.width())+'长度'+str(self.height()))
#第二种方式(mac下面板的坐标和长宽不包含标题)
#获取x,y
print('x坐标:'+str(self.geometry().x())+'y坐标'+str(self.geometry().y()))
#获取长宽
print('宽度'+str(self.geometry().width())+'长度'+str(self.geometry().height()))
#第三种
print('x坐标:'+str(self.frameGeometry().x())+'y坐标'+str(self.frameGeometry().y()))
print('宽度'+str(self.frameGeometry().width())+'长度'+str(self.frameGeometry().height()))
(10)弹出框的类型:对话框(QInputDialog),颜色框(QColorDialog)字体选择框(QFontDialog),文件选择框(QFileDialog)
QLineaEdit组件参考博客:https://www.cnblogs.com/ygzhaof/p/10059094.html
(11)QLineEdit 回显模式:
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QGridLayout,QLabel,QLineEdit
class BuddyDemo(QWidget):
def __init__(self):
super().__init__()
self.initGUI()
def initGUI(self):
self.setGeometry(300,300,300,200)
self.setWindowTitle("回显")
grid=QGridLayout()
self.setLayout(grid)
#普通的normal
label=QLabel('normal类型')
grid.addWidget(label,0,0)
lin1=QLineEdit()
#设置框内提示
lin1.setPlaceholderText('这是一个普通的lineedit')
lin1.setEchoMode(QLineEdit.Normal)
grid.addWidget(lin1,0,1)
#noEcho类型
label2=QLabel('normal类型')
grid.addWidget(label2,1,0)
lin2=QLineEdit()
#noEcho类型当输入是不显示输入字符
lin2.setPlaceholderText('这是一个noECho类型')
lin2.setEchoMode(QLineEdit.NoEcho)
grid.addWidget(lin2,1,1)
#password类型
label3=QLabel('password类型')
grid.addWidget(label3,2,0)
lin3=QLineEdit()
#password类型输入是显示的是点
lin3.setPlaceholderText('这是一个Password类型')
lin3.setEchoMode(QLineEdit.Password)
grid.addWidget(lin3,2,1)
#passwordEChoonEdit类型
label4=QLabel('passwordEChoonEdit类型')
grid.addWidget(label4,3,0)
lin4=QLineEdit()
lin4.setPlaceholderText('这是一个passwordEchoonEdit')
lin4.setEchoMode(QLineEdit.PasswordEchoOnEdit)
grid.addWidget(lin4,3,1)
self.show()
if __name__=='__main__':
app=QApplication(sys.argv)
demo=BuddyDemo()
sys.exit(app.exec_())
(12)QLineEdit验证
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QGridLayout,QLabel,QLineEdit
from PyQt5.QtGui import QIntValidator,QDoubleValidator,QRegExpValidator
from PyQt5.QtCore import QRegExp
class BuddyDemo(QWidget):
def __init__(self):
super().__init__()
self.initGUI()
def initGUI(self):
self.setGeometry(300,300,300,200)
self.setWindowTitle('验证')
grid=QGridLayout()
self.setLayout(grid)
#整数验证
label1=QLabel('QIntValidator')
grid.addWidget(label1,0,0)
edit1=QLineEdit()
#设置校验器
intv=QIntValidator()
intv.setRange(0,100) #只能输入0-100的整数
#绑定校验器
edit1.setValidator(intv)
#将组件添加到布局
grid.addWidget(edit1,0,1)
label2=QLabel('QdoubleValidator')
grid.addWidget(label2,1,0)
edit2=QLineEdit()
doublev=QDoubleValidator()
edit2.setValidator(doublev)
grid.addWidget(edit2,1,1)
#正则表达式验证
label3=QLabel('QRegExpValidator')
grid.addWidget(label3,2,0)
edit3=QLineEdit()
grid.addWidget(edit3,2,1)
reg=QRegExp('[a-z]+$') #匹配小写字母
validator=QRegExpValidator()
validator.setRegExp(reg)
edit3.setValidator(validator)
self.show()
if __name__=='__main__':
app=QApplication(sys.argv)
demo=BuddyDemo()
sys.exit(app.exec_())
(13)QLineEdit掩码
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QGridLayout,QLabel,QLineEdit
from PyQt5.QtGui import QIntValidator,QDoubleValidator,QRegExpValidator
from PyQt5.QtCore import QRegExp
class BuddyDemo(QWidget):
def __init__(self):
super().__init__()
self.initGUI()
def initGUI(self):
self.setGeometry(300,300,300,200)
self.setWindowTitle('验证')
grid=QGridLayout()
self.setLayout(grid)
#ip地址类型
label1=QLabel('IP')
grid.addWidget(label1,0,0)
edit1=QLineEdit()
grid.addWidget(edit1,0,1)
edit1.setInputMask('000.000.000.000;_')
#日期类型
label2=QLabel('Time')
grid.addWidget(label2,1,0)
edit2=QLineEdit()
grid.addWidget(edit2,1,1)
edit2.setInputMask('0000-00-00')
#许可证掩码
label3=QLabel('物理地址')
grid.addWidget(label3,2,0)
edit3=QLineEdit()
grid.addWidget(edit3,2,1)
edit3.setInputMask('>AAAA-AAAA-AAA;#')
self.show()
if __name__=='__main__':
app=QApplication(sys.argv)
demo=BuddyDemo()
sys.exit(app.exec_())
QTextEdit控件:
参考博文:https://blog.youkuaiyun.com/jia666666/article/details/81511435
QPushButton控件:
参考博文:https://blog.youkuaiyun.com/jia666666/article/details/81513443
QradioButton
参考:https://blog.youkuaiyun.com/jia666666/article/details/81514777
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow,QVBoxLayout,QWidget,QRadioButton
class RadioButtonDemo(QMainWindow):
def __init__(self):
super(RadioButtonDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('单选按钮')
self.setGeometry(300,300,300,200)
widget=QWidget()
#设置垂直布局
layout=QVBoxLayout()
widget.setLayout(layout)
self.setCentralWidget(widget)
self.radio1=QRadioButton('man')
layout.addWidget(self.radio1)
self.radio1.setChecked(True)
#绑定信号槽
self.radio1.toggled.connect(lambda :self.radioCheck(self.radio1)) #lambda另一种传值方式
self.radio2 = QRadioButton('woman')
layout.addWidget(self.radio2)
self.radio2.toggled.connect(lambda :self.radioCheck(self.radio2))
self.show()
def radioCheck(self,btn):
if btn.text()=='man'and btn.isChecked():
print('man')
if btn.text()=='woman'and btn.isChecked():
print('woman')
if __name__=='__main__':
app=QApplication(sys.argv)
demo=RadioButtonDemo()
sys.exit(app.exec_())
QCheckBox:
参考:https://blog.youkuaiyun.com/jia666666/article/details/81533763
一个特殊的方法:
setTriState()设置复选框为一个三态复选框
setCheckState()三态复选框的状态设置,具体设置
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow,QVBoxLayout,QWidget,QCheckBox
from PyQt5.QtCore import Qt
class RadioButtonDemo(QMainWindow):
def __init__(self):
super(RadioButtonDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('复选按钮')
self.setGeometry(300,300,300,200)
widget=QWidget()
#设置垂直布局
layout=QVBoxLayout()
widget.setLayout(layout)
self.setCentralWidget(widget)
checkbox1=QCheckBox('&C++') #&设置Alt+C的快捷键
layout.addWidget(checkbox1)
checkbox1.setChecked(True)
checkbox1.stateChanged.connect(self.checkChange)
checkbox2 = QCheckBox('java')
layout.addWidget(checkbox2)
checkbox2.setTristate(True)
checkbox2.setCheckState(Qt.PartiallyChecked)
checkbox2.stateChanged.connect(self.checkChange)
checkbox3 = QCheckBox('python')
layout.addWidget(checkbox3)
checkbox3.stateChanged.connect(self.checkChange)
self.show()
def checkChange(self):
btn=self.sender()
print(btn.text())
if btn.checkState()==0:
print('没选中')
if btn.checkState()==1:
print('半选')
if btn.checkState()==2:
print('选中')
if __name__=='__main__':
app=QApplication(sys.argv)
demo=RadioButtonDemo()
sys.exit(app.exec_())
QComboBox:
参考:https://blog.youkuaiyun.com/jia666666/article/details/81534260
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow,QVBoxLayout,QWidget,QComboBox,QLabel
from PyQt5.QtCore import Qt
class ComboBoxDemo(QMainWindow):
def __init__(self):
super(ComboBoxDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('复选按钮')
self.setGeometry(300,300,300,200)
widget=QWidget()
#设置垂直布局
layout=QVBoxLayout()
widget.setLayout(layout)
self.setCentralWidget(widget)
#下拉列表框
combox=QComboBox()
layout.addWidget(combox)
combox.addItem('c')
combox.addItem('c++')
combox.addItems(['java','python','js'])
combox.activated.connect(self.selectChange)
self.label=QLabel('显示选中的')
layout.addWidget(self.label)
self.show()
def selectChange(self):
box=self.sender()
self.label.setText(str(box.currentIndex()+1)+':'+box.currentText())
a=[box.itemText(i) for i in range(box.count())]
print(a)
if __name__=='__main__':
app=QApplication(sys.argv)
demo=ComboBoxDemo()
sys.exit(app.exec_())
QSpinBox:计数器控件
参考:https://blog.youkuaiyun.com/jia666666/article/details/81534431
QSpinbox计数器控件,允许用户选择一个整数值通过单击向上或向下或键盘上下键来增加减少当前显示的值,当然用户也可以输入值
默认情况下,QSpinBox的取值范围是0-99,每次改变的步长为1
QSpinBox和QDoubleSpinBox类均派生自QAbstractSpinBox类,QSpinBox用于处理整数值,QDoubleSpinBox则用于处理浮点数值,他们之间的区别就是处理数据的类型不同,其他功能基本相同,QDoubleSpinBox的默认精度是两位小数,但可以通过setDecimals()来改变
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow,QVBoxLayout,QWidget,QSpinBox
from PyQt5.QtCore import Qt
class SpinBoxDemo(QMainWindow):
def __init__(self):
super(SpinBoxDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('复选按钮')
self.setGeometry(300,300,300,200)
widget=QWidget()
#设置垂直布局
layout=QVBoxLayout()
widget.setLayout(layout)
self.setCentralWidget(widget)
#计数器框
spin=QSpinBox()
layout.addWidget(spin)
spin.setRange(1,10) #范围1到10,步长2
spin.setSingleStep(2)
spin.valueChanged.connect(self.valChange)
self.show()
def valChange(self):
box=self.sender()
print(box.value())
if __name__=='__main__':
app=QApplication(sys.argv)
demo=SpinBoxDemo()
sys.exit(app.exec_())
QSlider:QSlider控件提供一个垂直或者水平的滑动条,滑动条是一个用于控制有界值典型的控件,它允许用户沿水平或者垂直方向在某一范围内移动滑块,并将滑块所在的位置转换为一个合法范围内的整数值,有时候这中方式比输入数字或者使用SpinBox(计数器·)更加自然,在槽函数中对滑块所在位置的处理相当于从整数之间的最小值和最高值进行取值
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow,QVBoxLayout,QWidget,QSlider,QLCDNumber
from PyQt5.QtCore import Qt
class SliderDemo(QMainWindow):
def __init__(self):
super(SliderDemo, self).__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('demo')
self.setGeometry(300,300,300,200)
widget=QWidget()
#设置垂直布局
layout=QVBoxLayout()
widget.setLayout(layout)
self.setCentralWidget(widget)
#滑块
slider=QSlider(Qt.Horizontal)
layout.addWidget(slider)
slider.setTickPosition(QSlider.TicksBelow)
slider.setTickInterval(10)
slider.valueChanged.connecta(self.valChange)
slider.setRange(0,100)
self.lcd=QLCDNumber()
layout.addWidget(self.lcd)
self.show()
def valChange(self):
sp=self.sender()
print(sp.value())
self.lcd.display(sp.value())
if __name__=='__main__':
app=QApplication(sys.argv)
demo=SliderDemo()
sys.exit(app.exec_())
QMessageBox: