最近抽空学习一下Python的GUI编程库PyQt5,主要看的一些书籍(这方面的书相对较少,中文的多为PyQt4开发,而其与PyQt5并不兼容)和视频学习资料,视频的话推荐Bilibili播放量最高的PyQt5教程,来自网易云课堂。由于Python语言也在学习阶段,并且PyQt5里面很多方法的实现都相对较为容易(高度集成),所以我选择了PyQt5作为GUI的开发环境。安装的话两行命令带过:
pip install PyQt5
pip install PyQt5-tools
换源后可能还是有点卡,多试几次就可以了。环境配置很简单,代码直接调用库就可以实现GUI设计,而如果想用QtDesigner的话就得配置C++环境了,这个比较复杂,不过网上有解答。再比较PyQt4的环境配置,真的就有点不友好了,反正我是没成功。。
Windows 10
Sublime 3
Python 3.6+PyQt5 5.15
在介绍这两个控件之前,先介绍一下PyQt5库的一些基本类以及屏幕坐标系一些参数的区别,然后给出一个面向对象编写GUI的基本框架,这是开发PyQt GUI的前提。
QAppplication:基类,开发每一个GUI都要先实例化QApplication这个父类。
QMainWindow:主窗口类,主窗口的开发要继承自这个父类。可以包含菜单栏、工具栏、状态栏和标题栏。
QDialog:对话框类,用于临时弹出的消息,在Windows系统下可以通过ESC键关闭。不可包含菜单栏、工具栏、状态栏和标题栏。
QWidget:未确定窗口类型时候使用该类。
一个GUI主窗口通常包含以下几部分:
下面以Qt开发的LyX为例介绍上述几个部分。
使用.x()
和.y()
方法分别获得主窗口的x和y坐标,需要注意的是这里的两个坐标均为包含边框宽度的像素值,也即move()
方法设置的值。
使用.width()
和.height()
方法分别获得主窗口的宽度和高度的像素值,需要注意的是这里的两个值均为不包含边框宽度的像素值,也即resize()
方法设置的值。
使用.geometry().x()
和.geometry().y()
方法分别获得主界面(即不包含标题栏及外边框)左上角点的x和y坐标(单位:px)。
使用.frameGeometry().width()
和.frameGeometry().height()
方法分别获得整个主窗口(包含标题栏及外边框)的宽度和高度(单位:px)。
使用.geometry().width()
和.geometry().height()
方法与.width()
和.height()
方法得到相同的值。
使用.frameGeometry().x()
和.frameGeometry().y()
方法与.x()
和.y()
方法得到相同的值。
下面这个图就是由PyQt5生成的GUI,可以看到其上、左、右都有边框,且边框宽度为1px,而标题栏的宽度为45px,这就解释了上面函数为什么会带来差异。
具体的代码可以看这里:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
def onClick_Btn1():
# 输出相应的信息
# 窗口的x和y
print("坐标为(%dpx,%dpx),其宽度为%dpx,高度为%dpx"%(widget.x(),
widget.y(), widget.width(), widget.height()))
# 第二种方法
print("坐标为(%dpx,%dpx),其宽度为%dpx,高度为%dpx"%
(widget.geometry().x(), widget.geometry().y(),
widget.geometry().width(), widget.geometry().height()))
# 第三种方法
print("坐标为(%dpx,%dpx),其宽度为%dpx,高度为%dpx"%
(widget.frameGeometry().x(), widget.frameGeometry().y(),
widget.frameGeometry().width(), widget.frameGeometry().height()))
app = QApplication(sys.argv)
widget = QWidget()
btn = QPushButton(widget)
btn.setText("按钮1")
btn.clicked.connect(onClick_Btn1)
btn.move(45, 45)
# 设置窗口尺寸
widget.resize(500,500)
widget.move(300,300)
widget.setWindowTitle("屏幕坐标系")
widget.show()
sys.exit(app.exec_())
下面是一个基本模板,面向对象进行GUI窗口的创建及配置。
import sys # 导入系统库
from PyQt5.QtWidgets import * # 导入一些必需的组件
# 定义窗口类,继承自父类QMainWindow
class PyQt5GUIDemo(QMainWindow):
def __init__(self):
# 继承父类的属性
# 也可简写为super().__init__()
super(PyQt5GUIDemo, self).__init__()
self.initUI()
def initUI(self):
# 设置窗口标题
self.setWindowTitle("我的GUIDemo")
# 设置窗口的宽、高,单位为屏幕像素(px)
self.resize(400, 300)
# 设置窗口左上角在屏幕坐标系中的位置
# 坐标系以左上角的点为原点
# 调用格式为move(x, y),单位(px)
self.move(300, 300)
# 多文件时用于防止非主文件代码执行
if __name__ == '__main__':
# 实例化基类QApplication
# sys.argv表示接受用户输入
# 这里实质上是用户对GUI窗口的键鼠操作
app = QApplication(sys.argv)
# 实例化上述定义的窗口类
main = PyQt5GUIDemo()
main.show() # 显示窗口
# 使窗口正常退出,并释放内存
sys.exit(app.exec_())
QLabel控件是控制窗口基本参数的类,主要用于窗口字体的对齐及一些字符的处理等。
setAlignment()
:设置文本对齐方式
setIndent()
:设置文本缩进
text()
:获取文本内容
setBuddy()
:设置伙伴关系(伙伴控件)
setText()
:设置文本内容,支持HTML标签(超链接)
selectedText()
:返回所选字符
setWordWrap()
:设置是否允许换行
setToolTip()
:设置按钮提示
当鼠标滑过QLabel控件时触发:linkHovered
当鼠标单击QLabel控件时触发:linkActivated
这里仅展示部分代码,全部代码可以看B站课程下面评论区的资料。
import sys
from PyQt5.QtWidgets import QMainWindow,QApplication,QLabel,QWidget
from PyQt5.QtGui import QPixmap, QPalette
# 导入Qt类用于设置对齐方式调用PyQt内置的颜色等
from PyQt5.QtCore import Qt
label1 = QLabel()
label2 = QLabel()
label3 = QLabel()
label4 = QLabel()
label1.setText("文本标签")
# 设置显示背景色
label1.setAutoFillBackground(True)
palette = QPalette()
palette.setColor(QPalette.Window,Qt.blue) # 设置背景色
label1.setPalette(palette)
# 居中对齐
label1.setAlignment(Qt.AlignCenter)
label2.setText("GUI实例")
# 设置居中对齐
label3.setAlignment(Qt.AlignCenter)
label3.setToolTip('图片标签')
label3.setPixmap(QPixmap("./1.jpg"))
# 如果设为True,用浏览器打开网页
# 如果设为False,调用槽函数
label4.setOpenExternalLinks(True)
label4.setText("百度一下")
# 设置右对齐
label4.setAlignment(Qt.AlignRight)
label4.setToolTip('超链接')
def Hovered(self):
print('鼠标滑过label2触发事件')
def Clicked(self):
print('鼠标单击label4触发事件')
label2.linkHovered.connect(Hovered)
label4.linkActivated.connect(Clicked)
本文主要讲解了PyQt5开发PythonGUI窗口的基本框架以及QLabel控件的一些属性、方法及使用,由于PyQt5的高度模块化,GUI的开发也变得相对容易,而使用Python自带的Tkinter开发GUI又有功能较少、结构单一等缺点,所以PyQt5可以是个不错的选择。