一.PyQt5简介

PyQt5是一个用于创建图形用户界面(GUI)应用程序的跨平台工具集,它将Qt库(广泛用于C++编程语言中创建丰富的GUI应用程序)的功能包装给Python使用者。PyQt5是由Riverbank Computing开发的,并且可以在所有主流操作系统上运行,包含Windows、macOS和Linux。

PyQt5包括了超过620个类和6000个函数和方法。这个框架支持包括SQL数据库、线程、Unicode、正则表达式、网络编程等高级功能。除了GUI功能外,PyQt5还允许用户访问Qt的模型/视图架构和QML(Qt Modeling Language),这是一种专门为创建动态和自定义用户界面而设计的语言。

二.环境搭建

1.终端使用pip安装PyQt5库

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple PyQt5

2.如果出现Could not build wheels for PyQt5_sip, which is required to install pyproject.toml-based projects报错信息

3.先安装 Visual Studio 后再安装PyQt5即可,终端执行如下指令

wget https://aka.ms/vs/17/release/vs_BuildTools.exe -o vs_BuildTools.exe ; cmd /c vs_BuildTools.exe

勾选C++/CLI后安装就行

三.基本用法

1.PyQt5常见的模块

QApplication 这个类管理GUI应用程序的控制流和主要设置,并且是每个PyQt5应用程序中必须有的部分
QWidget 所有用户界面对象的基类。当你想创建一个自定义的窗口时,你会使用或者继承这个类
QLabel 用于展示文本或图片的类
QtCore 其他模块使用的核心非 GUI 类
QAction 用于处理菜单栏、工具栏或快捷键等的动作。
QtSql 使用 SQL 进行数据库集成的类
QtXml 处理 XML 的类
QSlider 滑动条,让用户通过滑动选择一个数值。

2.一个简单的窗口创建

importsysfrom PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets importQWidget, QLabel, QMessageBox, QApplicationdefwindows():#创建一个 QApplication 类的应用程序对象
    app =QApplication(sys.argv)#基于QWidget类声明窗口
    w =QWidget()#添加一个QLabel对象,并将标签添加“helloworld”文本。
    b =QLabel(w)
b.setText(
"Hello World!")#设置文本控件在窗口中的位置(x,y) b.move(50, 50)#设置label控件的长和宽 b.resize(100,20)#设置字体样式大小 font =QFont()
font.setFamily(
"Arial") #字体样式,中文英文都可(“楷体”) font.setPointSize(20) #字体大小 b.setFont(font)#通过 setGeometry() 方法定义窗口的大小和位置(x,y,w,h) w.setGeometry(100, 100, 500, 1000)#设置窗口标题 w.setWindowTitle("PyQt5") #显示窗口 w.show()#进入应用程序的主循环app.exec_()方法(窗口一直显示) sys.exit(app.exec_())if __name__ == '__main__':
windows()

备注写的很详细了,这里就不一一介绍每行代码的意思了。

3.窗口icon设置

importsysfrom PyQt5.QtGui import *
from PyQt5.QtWidgets import QWidget, QApplication  #导入尽量用具体类,不用*


classWindow(QWidget):def __init__(self, parent=None):
super().
__init__(parent)
self.initUI()
self.setGeometry(
100, 100, 500, 500)
self.setWindowTitle(
"PyQt5")#设置icon definitUI(self):
self.setWindowIcon(QIcon(
'./2.jpg')) #设置窗口左上角icon defmain():
app
=QApplication(sys.argv)
ex
=Window()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

上述代码中,我们在initUI函数中,调用父类setWindowIcon()方法去设置窗口icon,在Window类中初始化时去调用initUI函数来实现设置icon。

4.QLabel控件

    defqlabel(self):
font
=QFont()
font.setFamily(
"Arial")
font.setPointSize(
16)
label
=QLabel(self)
label.setText(
"Hello World") #设置文本 label.setFont(font) #设置文本字体类型及大小 label.move(50, 20) #控件在窗口的位置

这里和如上写法一致,在Window类中写一个qlabel函数,里面去调用QLabel,再在Window类中初始化时调用这个函数即可(使用QLabel模块时需提前导入该模块),我们来看下结果。

5.tips信息提示框

    deftips(self):#创建一个按钮控件
        btn = QPushButton('Button', self)#设置文本字体及大小
        btn.setFont(QFont('SansSerif', 50))#设置tips
        btn.setToolTip('This is a widget')#设置按钮在窗口的位置
        btn.move(100, 100)

效果如下,鼠标悬浮在button上时,会出现tips信息弹框。

6.关闭二次确定弹框

主动关闭窗口(即点击窗口右上角X),弹出二次确定弹框,提示是否关闭。

importsysfrom PyQt5.QtGui import *
from PyQt5.QtWidgets import QWidget, QApplication, QMessageBox, QDesktopWidget  #导入尽量用具体类,不用*


classWindow(QWidget):def __init__(self, parent=None):
super().
__init__(parent)
self.initUI()
self.setGeometry(
100, 100, 500, 500)
self.setWindowTitle(
"PyQt5")
self.center()
#设置icon definitUI(self):
self.setWindowIcon(QIcon(
'./2.jpg'))def closeEvent(self, event): #关闭二次确定弹框 reply = QMessageBox.question(self, '是否关闭',"Are you sure to quit?", QMessageBox.Yes, QMessageBox.No)if reply ==QMessageBox.Yes:
event.accept() # 关闭窗口
else:
event.ignore() # 不关闭
def center(self): #设置窗口居中 qt = self.frameGeometry() #获取需要操作的窗口位置,长宽(即设置的setGeometry) cp = QDesktopWidget().availableGeometry().center() #获取电脑分辨率 qt.moveCenter(cp) #获取电脑中间位置 self.move(qt.topLeft()) #将窗口移动到中间位置 defmain():
app
=QApplication(sys.argv)
ex
=Window()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

上述代码中重写了父类中的closeEvent方法,通过QMessageBox.question()来获取用户行为,event.accept()来确定关闭窗口。

7.关闭窗口事件

    defclos(self):
qbtn
= QPushButton('Quit', self) #创建一个按钮 qbtn.clicked.connect(QCoreApplication.instance().quit) #回调关闭事件 qbtn.setToolTip("点击关闭窗口") #tips提示 qbtn.move(0, 0)

如下图效果,鼠标点击Quit按钮后窗口关闭,其效果和关闭按钮X一致。

8.菜单栏和工具栏

QMainWindow
用于创建主应用程序窗口的类。它是
QWidget
的一个子类,提供了创建具有菜单栏、工具栏、状态栏等的主窗口所需的功能。

1)状态栏

importsysfrom PyQt5.QtWidgets importQMainWindow, QApplicationclassExample(QMainWindow):def __init__(self):
super().
__init__()
self.initUI()
definitUI(self):
self.setGeometry(
100, 100, 500, 500)
self.setWindowTitle(
'Statusbar')
self.statusBar().showMessage(
"状态栏") #设置状态栏 if __name__ == '__main__':
app
=QApplication(sys.argv)
ex
=Example()
ex.show()
sys.exit(app.exec_())

状态栏的设置很简单,通过调用QMainWindow的statusBar()方法创建状态栏,showMessage()来设置状态栏显示的文本。

2)菜单栏

    defbar(self):
action
= QAction(QIcon('./2.jpg'), '登录', self) #创建QAction实例 action.setShortcut('Ctrl+a') #设置快捷键操作 action.setStatusTip('登录') #状态栏提示,窗口的左下角出现,鼠标悬停在选项上会出现 action.triggered.connect(qApp.quit) #点击事件后回调的方法(qApp.quit关闭窗口) menubar= self.menuBar() #创建一个菜单栏 menu = menubar.addMenu('File') #设置菜单栏tab menu.addAction(action)#关联事件

用过menuBar()创建一个菜单栏,并添加addMenu()tab项,通过addAction()添加QAction行为动作,具体效果如下。

triggered.connect(qApp.quit)设置了触发动作后回调事件,即点击登录选项或快捷键Ctrl+A时会触发qApp.quit关闭窗口。上诉中我们只创建了一个菜单栏并只绑定了一个QAction如果想要多个菜单栏多个动作,可以创建多个addMenu(),下面看下具体实例。

   defbar(self):
action
= QAction(QIcon('./2.jpg'), '登录', self) #创建QAction实例 action.setShortcut('Ctrl+a') #设置快捷键操作 action.setStatusTip('登录') #状态栏提示,窗口的左下角出现,鼠标悬停在选项上会出现 action.triggered.connect(qApp.quit) #点击事件后回调的方法(qApp.quit关闭窗口) action1= QAction(QIcon('./2.jpg'), '登录', self) #创建QAction实例 action1.setShortcut('Ctrl+a') #设置快捷键操作 action1.setStatusTip('退出') #状态栏提示,窗口的左下角出现,鼠标悬停在选项上会出现 action1.triggered.connect(qApp.quit) #点击事件后回调的方法(qApp.quit关闭窗口) menubar= self.menuBar() #创建一个菜单栏 menu = menubar.addMenu('File') #设置菜单栏tab menubar1 = self.menuBar() #创建一个菜单栏 menu1 = menubar1.addMenu('File1') #设置菜单栏tab menu.addAction(action)#关联事件 menu.addAction(action1) #关联事件

3)子菜单栏

上面我们只是实现了一级菜单栏,那么在需求中要求创建二级,三级或者多级菜单,此时就需要用到QMenu()来创建下拉菜单栏了,我们先来看下二级菜单栏的创建。

    #创建子菜单
    defbar_z(self):
menubar
= self.menuBar() #创建菜单栏 menu = menubar.addMenu('File') #设置菜单栏tab newmenu= QMenu('一级下拉框', self) #创建一个下拉菜单 impAct = QAction('二级目录', self) #设置一个动作 impAct.triggered.connect(self.btn) #点击事件后回调的方法 newmenu.addAction(impAct) #添加动作到下菜单中 newact= QAction('一级目录', self) #创建动作 menu.addAction(newact)#添加动作到菜单栏 menu.addMenu(newmenu) #添加下拉菜单到菜单栏 defbtn(self):#创建一个按钮控件 btn = QPushButton('Button', self)#btn.setGeometry(100, 100, 80, 30) btn.move(100, 100)
btn.setToolTip(
"button")
btn.show()

如果我们想创建三级目录甚至更多级的目录,可以创建多个下拉菜单栏,并通过addMenu()添加进去,下面看下具体实现。

#创建子菜单
    defbar_z(self):
menubar
= self.menuBar() #创建菜单栏 menu = menubar.addMenu('File') #设置菜单栏tab newmenu1= QMenu('二级下拉框', self) #创建一个下拉菜单 impAct1 = QAction('三级目录', self) #设置一个动作 impAct1.triggered.connect(self.btn) #点击事件后回调的方法 newmenu1.addAction(impAct1) #添加动作到下菜单中 newmenu= QMenu('一级下拉框', self) #创建一个下拉菜单 impAct = QAction('二级目录', self) #设置一个动作 impAct.triggered.connect(self.btn) #点击事件后回调的方法 newmenu.addAction(impAct) #添加动作到下菜单中 newmenu.addMenu(newmenu1) #添加下拉菜单栏到二级菜单下 newact= QAction('一级目录', self) #创建动作 menu.addAction(newact)#添加动作到菜单栏 menu.addMenu(newmenu) #添加下拉菜单到菜单栏

4)带复选框的菜单

    defbar_checkable(self):
menubar
=self.menuBar()
bar_menu
= menubar.addMenu('View') #添加菜单栏 statact = QAction('复选框', self, checkable=True) #创建一个可以勾选的动作 statact.setStatusTip('View statusbar')
statact.setChecked(True)
#设置默认选中 statact.triggered.connect(self.menu)
bar_menu.addAction(statact)
defmenu(self, state):ifstate:print("勾选后执行的事件") #勾选了 else:print("取消勾选执行的事件") #取消勾选

QAction()中,checkable=True表示可以勾选的动作。

5)右键栏

鼠标悬浮再窗口上,右击打开的菜单栏,此功能需要重写父类中contextMenuEvent()方法,看下代码演示。

    defcontextMenuEvent(self, event):
rightmenu
= QMenu(self) #创建一个下拉菜单 #添加动作 d = rightmenu.addAction("打印")
q
= rightmenu.addAction("退出")
ture
= rightmenu.addAction("确定")
action
= rightmenu.exec_(self.mapToGlobal(event.pos())) #exec_()显示菜单。获取动作行为 if action ==d:
self.btn()
elif action ==q:
qApp.quit()
#关闭窗口 else:print("无确定内容")

6)工具栏

工具栏可以理解为是多个动作的集合,可以将多个QAction()添加展示出来。

    def bar_tool(self):  #多个动作集合
        action = QAction("工具1",self)
action2
= QAction("工具2",self)
action.setStatusTip(
"点击退出")
action.triggered.connect(qApp.quit)
toolbat
= self.addToolBar("工具栏") #创建一个工具栏 toolbat.addAction(action) #将动作添加到工具栏 toolbat.addAction(action2) #将动作添加到工具栏

7)主窗口显示

这个就不做过多介绍,在初始__init__中调用上诉几种方法即可,默认菜单栏在最顶部,添加的动作会更加调用的先后从左到右排列,工具栏默认在菜单栏下发,这里只看下效果截图。

9.页面布局

1)坐标布局


importsysfrom PyQt5.QtGui importQIconfrom PyQt5.QtWidgets importQLabel, QApplication, QWidgetclassExample(QWidget):def __init__(self):
super().
__init__()
self.initUI()
definitUI(self):
self.setGeometry(
100, 100, 500, 500)
self.setWindowTitle(
'Statusbar')
q1
= QLabel("quit", self)
q2
= QLabel("quit2", self)
q3
= QLabel("quit3", self)
q1.move(
20, 20) #坐标布局 q2.move(20, 80) #坐标布局 q3.move(20, 140) #坐标布局 if __name__ == '__main__':
app
=QApplication(sys.argv)
ex
=Example()
ex.show()
sys.exit(app.exec_())

坐标布局

上述中通过move(x, y)方法来设置qlable的位置

2)界面比例布局


importsysfrom PyQt5.QtGui importQIconfrom PyQt5.QtWidgets importQApplication, QPushButton, QHBoxLayout, QWidgetclassExample(QWidget):def __init__(self):
super().
__init__()
self.initUI()
self.button()
definitUI(self):
self.setGeometry(
100, 100, 500, 500)
self.setWindowTitle(
'Statusbar')def button(self): #比例布局 ok = QPushButton("ok") #创建三个按钮 cancel = QPushButton("cancel")
cancel1
= QPushButton("cancel1")

hbox1
= QHBoxLayout() #创建一个水平布局 hbox1.addWidget(ok) #添加按钮到水平布局中 hbox1.addStretch(1) #设置水平比例间距 hbox1.addWidget(cancel)#添加按钮到水平布局中 hbox1.addStretch(1) #设置水平比例间距 hbox1.addWidget(cancel1)
hbox1.addStretch(
6)

self.setLayout(hbox1)
#添加到布局器 if __name__ == '__main__':
app
=QApplication(sys.argv)
ex
=Example()
ex.show()
sys.exit(app.exec_())

水平布局

上面代码中通过QHBoxLayout() 创建一个水平布局,addWidget()将按钮添加到布局中,再通过addStretch()来设置比例间距,可以看到设置的比例为1:1:6


importsysfrom PyQt5.QtGui importQIconfrom PyQt5.QtWidgets importQApplication, QPushButton, QHBoxLayout, QVBoxLayout, QWidgetclassExample(QWidget):def __init__(self):
super().
__init__()
self.initUI()
self.button()
definitUI(self):
self.setGeometry(
100, 100, 500, 500)
self.setWindowTitle(
'Statusbar')def button(self): #比例布局 ok = QPushButton("ok") #创建三个按钮 cancel = QPushButton("cancel")
cancel1
= QPushButton("cancel1")

hbox
= QHBoxLayout() #创建一个水平布局 hbox.addStretch(1) #设置水平比例间距(只设置一个stretch,会将按钮挤到最右侧。若stretch写在addWidget下面,则按钮会被寄到最左侧) hbox.addWidget(ok) #添加按钮到水平布局中 hbox.addWidget(cancel)

vbox
= QVBoxLayout() #创建一个垂直布局 vbox.addStretch(1) #设置垂直比例间距(只设置一个stretch,会将按钮挤到最下面。若stretch写在addlayout下面,则按钮会被寄到最下面) vbox.addLayout(hbox) #将刚刚创建的水平布局添加到垂直布局中 self.setLayout(vbox)#将垂直布局加到布局器中(按钮位于页面右下角) if __name__ == '__main__':
app
=QApplication(sys.argv)
ex
=Example()
ex.show()
sys.exit(app.exec_())

垂直布局

3)栅格化布局


importsysfrom PyQt5.QtGui importQIconfrom PyQt5.QtWidgets importQApplication, QPushButton, QWidget, QGridLayoutclassExample(QWidget):def __init__(self):
super().
__init__()
self.initUI()
self.Grid()
definitUI(self):
self.setGeometry(
100, 100, 500, 500)
self.setWindowTitle(
'Statusbar')def Grid(self): #栅格化的按钮 grid = QGridLayout() #创建一个栅格化布局 name = ["7", "8", "9", "/","4", "5", "6", "x","1", "2", "3", "-","清除", "0", ".", "="]#列表推导式 pos = [(x, y) for x in range(4) for y in range(4)]for names, p in zip(name, pos): #同时迭代两个序列 button = QPushButton(names) #创建按钮 grid.setSpacing(10) #设置各个单元格之间的间距 grid.addWidget(button, *p) #添加到栅格化布局中 self.setLayout(grid) #将栅格化布局加到布局器 if __name__ == '__main__':
app
=QApplication(sys.argv)
ex
=Example()
ex.show()
sys.exit(app.exec_())

栅格化布局

效果图

栅格化布局理论上也是通过坐标来定位的,通过列表推导式可到得到几个坐标(0,0)(0,1)(0,2)(1,0)(1,1)(1,2)..........,然后再通过坐标去逐个添加。

4)实例


importsysfrom PyQt5.QtGui importQIconfrom PyQt5.QtWidgets importQLabel, QApplication,QWidget, QGridLayout, \
QLineEdit, QTextEdit
classExample(QWidget):def __init__(self):
super().
__init__()
self.initUI()
self.input()
definitUI(self):
self.setGeometry(
100, 100, 500, 500)
self.setWindowTitle(
'Statusbar')definput(self):
grid
=QGridLayout()#设置标签 title = QLabel("title")
Author
= QLabel("Author")
Review
= QLabel("Review")#设置输入框 titleEdit = QLineEdit() #行编辑 authorEdit =QLineEdit()
reviewEdit
= QTextEdit() #文版编辑 grid.setSpacing(10) #设置间距 grid.addWidget(title, 0, 0)
grid.addWidget(titleEdit, 0,
1)
grid.addWidget(Author,
1, 0)
grid.addWidget(authorEdit,
1, 1)
grid.addWidget(Review,
2, 0)
grid.addWidget(reviewEdit,
2, 1)

self.setLayout(grid)
if __name__ == '__main__':
app
=QApplication(sys.argv)
ex
=Example()
ex.show()
sys.exit(app.exec_())

实例

上述中实例通过QGridLayout()来将QLabel(), QLineEdit(行编辑)  ,QTextEdit(文版编辑) 进行的整合使用,下面看下结果。

四.实例

以一个简单计算器功能为例,先来看下代码实现和效果展示


importsysfrom PyQt5.QtGui importQIconfrom PyQt5.QtWidgets importQApplication, QPushButton, QWidget, QGridLayout, \
QLineEdit
classExample(QWidget):def __init__(self):
super().
__init__()
self.initUI()
self.Grid()
definitUI(self):
self.setGeometry(
100, 100, 500, 500)
self.setWindowTitle(
'Statusbar')def Grid(self): #栅格化的按钮 grid =QGridLayout()
hbox
=QLineEdit()
grid.addWidget(hbox, 0, 0,
1, 4)
name
=["7", "8", "9", "/","4", "5", "6", "*","1", "2", "3", "-","清除", "0", ".", "="]#列表推导式 pos = [(x, y) for x in range(1,5) for y in range(4)]for names, p in zip(name, pos): #同时迭代两个序列 if names == "":continue elif names == "hbox":
grid.addWidget(hbox,
*p)else:
button
=QPushButton(names)
grid.addWidget(button,
*p)
button.clicked.connect(
lambda checked, btn_text=names: on_button_clicked(btn_text))
grid.setSpacing(
10) #设置各个单元格之间的间距 self.setLayout(grid)defon_button_clicked(btn_text):try:if btn_text == "清除":
hbox.clear()
elif btn_text == "=":
str_num
=eval(hbox.text())
hbox.clear()
hbox.insert(str(str_num))
else:
hbox.insert(btn_text)
except:
hbox.insert(
"error")if __name__ == '__main__':
app
=QApplication(sys.argv)
ex
=Example()
ex.show()
sys.exit(app.exec_())

计算器

使用addWidget将输入框添加到栅格化布局中,后面无个参数分别表示:(添加对象,x位置,y位置,占据的单元格高度,占据的单元格宽度)。

grid.addWidget(hbox, 0, 0, 1, 4)

QLineEdit()几个常用的方法

        hbox =QLineEdit()
hbox.setText(
"默认文案") #设置默认文案 hbox.setPlaceholderText("暗文") #当输入框内容为空时显示该文案 hbox.insert("243") #添加 print(hbox.text()) #获取框内容 hbox.clear() #清空

五.打包

可参考:https://www.cnblogs.com/lihongtaoya/p/17349911.html

文章来源:https://www.cnblogs.com/lihongtaoya/ ,请勿转载

标签: none

添加新评论