PyQt5

text::Python


一、PyQt5安装

PyQt5库

C++PyQt5库

安装:pip install PyQt5 -i https://pypi.douban.com/simple


二、QT designer

安装:

  • 安装 配置 版本问题 3.9.0a4不行
  • pip install PyQt5-tools -i https://pypi.douban.com/simple
  • python版本要在 3.10 以下且3.9.0a4不行
  • pycharm External Tools页面位置:File > Settings > Tools > External Tools

配置工具:

  • Name:QtDesigner:

    • Program:(Python安装路径)\Lib\site-packages\qt5_applications\Qt\bin\designer.exe
    • Working directory:$ProjectFileDir$
  • QtDesigner制作UI界面,生成.ui文件,需要通过PyUIC转换成.py文件:

    • Name:PyUIC
    • Program:(Python安装路径)
    • Arguments:-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py
    • Working directory:$FileDir$
  • PyRcc可以将图片、数据文件资源打包成py文件:

    • Name:PyRcc
    • `Program:(Python安装路径)

    • Arguments:-m PyQt5.pyrcc_main $FileName$ -o $FileNameWithoutExtension$_rc.py

    • Working directory:$FileDir$

# 加载ui文件
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5 import uic

if __name__ == '__main__':
app = QApplication(sys.argv)
ui = uic.loadUi("./untitled.ui")
ui.show()
app.exec_()

三、PyQt5.QtWidgets

1 窗口

1.1 简单案例

import sys

if __name__ == '__main__':
# 调用本程序
app = QApplication(sys.argv)
# 设置名称
app.setApplicationName("Hello World")
# 初始化窗体
w = QWidget()
# 设置窗口标题
w.setWindowTitle("Hello World")
# 展示窗口
w.show()
# 程序进行循环等待状态
app.exec_()

1.2 格式案例

import sys

class MyWindow(QWidget):
def __init__(self):
super(MyWindow, self).__init__()
# 设置窗口标题
self.setWindowTitle("系统")

if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWindow()
w.show()
app.exec_()

1.3 窗口类型

QWidget:控件和窗口的父类,自由度高(无其他区域),没有划分菜单、工具栏、状态栏、主窗口等区域。

QMainWindow:是 QWidget 的子类,包含菜单栏、工具栏、状态栏、标题栏等,中间部分则为主窗口区域。

QDialog:对话框窗口的基类。

QMessage:消息窗口。

1.4 QDialog

QDialog

QFileDialog使用:

  • QFileDialog

  • 例:image_file, _ =QFileDialog.getOpenFileName(self,'Open file','C:\\','Image files (*.jpg *.gif *.png *.jpeg)')

QFileDialog参数:

  1. self:用于指定父组件。
  2. open file:是QFileDialog对话框的标题。
  3. C:\\:\’默认打开的目录,Linux 和 Windows 杠不同,””表示当前目录。
  4. 对话框中文件扩展名过滤器(fliter),比如使用Image files (.jpg .gif .png .jpeg)表示只能显示扩展名为.jpg, .gif等文件。

1.5 QMessage

QMessage

QMessageBox.Critical:错误窗口

1.6 窗口属性

# 设置窗口大小
obj.resize(x,y)
# 移动屏幕至目标位置
obj.move(x,y)
# 对象的 x , y , w , h
obj.frameGeometry()

# 设置风格
obj.setStyleSheet("backgroud-color:grey;")
# 设置中心内容显示
obj.setCentralWidget(label)

# Mac菜单栏会在屏幕顶部而非程序顶部,该设置为真可以让Mac也同Windows一样
menu.setNativeMenuBar(False)

1.7 案例

隐藏标题栏:

# 设置窗口显示在正中心
# 通用代码
width = 300
height = 300
window.resize(width , height)
# 获得物体左上角的点在中心的坐标
center_point = QDesktopWidget().availableGeometry().center()
x = center_point.x()
y = center_point.y()

# 方法1:
window.move(x - width // 2,y - height // 2)

# 方法2:
# 获得框架的 x , y , w , h
old_x,old_y,wi,he = w.frameGeometry().getRect()
window.move(x - wi // 2, y - he // 2)
window.show()

# 直接设置
self.setCentralWidget(container)

2 控件

2.1 按钮

按钮

# 展现按钮
bin = QPushButton( "按钮" )
bin.setParent( window ) # 在父物体上展示
# 或者
bin = QPushButton( "按钮" , w )

2.2 文本

# 标签
label = QLabel("账号:", window )

2.3 文本框

QPlainTextEdit

常用信号

# QLineEdit
# 文本框
line = QLineEdit( window )
# 函数结束才显示文本
line.setPlainText(res)
# 框中自动显示文本
line.setPlaceholderText( "text" )
# 获得文本
line.text()

# QPlainTextEdit,类记事本。
text = QPlainTextEdit()
# 获得文本
text.toPlainText()

undo # 撤回
redo # 前进

2.4 选项框

# 选项组
hobby_box = QGroupBox("爱好")
# 单个选项
bt1 = QRadioButton("抽烟")
# 添加按钮到组
hobby_box.addButton(bt1)

# 下拉框
Qbox = QComboBox()
# 添加选项们到下拉框中,字典,键是名字,值是返回值。
Qbox.addItems(dict)
# 下拉框值改变发送信号
QBox.currentTextChanged[str].connect(slot)

2.5 滚动对象

QScrollArea()

# 添加自动滚动条
scroll = QScrollArea()
v_layout = QVBoxLayout()
v_layout.addWidget(scroll)

2.6 计数器

# 计数器
spin = QSpinBox()

# 设置范围
spin.setRange(min,max,[step=1])
# 其他单个设置
spin.spin.setMinimum()
spin.setMaximum()
spin.setValue()
spin.singleStep()
# 返回属性值
spin.value()

# 值改变信号
spin.valueChanged.connect(slot)

2.7 表格

author::QTableWidget

self.table_widget = QTableWidget()

# 设置表格行列数
self.table_widget.setRowCount(row)
self.table_widget.setColumnCount(col)

# 隐藏行数显示
self.table_widget.verticalHeader().setVisible(False)

# 设置表头
self.table_widget.setHorizontalHeaderLabels([ "账号", "密码"])
# 表头加粗
font = self.table_widget.horizontalHeader().font()
font.setBold(True)
self.table_widget.horizontalHeader().setFont(font)
# 表列宽
self.table_widget.horizontalHeader().resizeSection(index,size)

# 禁用编辑功能
item.setFlags(item.flags() & ~Qt.ItemIsEditable)

# 绑定监听双击
self.table_widget.cellDoubleClicked.connect(self.inspect) # 连接双击信号和 inspect 槽函数
def inspect(self,row,col):
print("Clicked on row:", row)
print("Clicked on column:", col)

2.8 控件属性

# 返回属性值
obj.value()

# 设置位置和宽高
obj.setGeometry(x,y,w,h)
# 设置固定宽高
obj.setFixedSize(x,y)
# 框架的 x , y
obj.frameSize()

# 自动换行
obj.setWordWrap(True)
# 显示内容靠上
obj.setAlignment(Qt.AlignTop)

# 设置文本(html)
obj.setText / setPlainText(text)
# 设置注释(在下面)
obj.setStatusTip(text)
# 设置快捷键
obj.setShortcut("Ctrl+N")
# 设置文本框显示格式(全窗口显示或非全窗口显示)
setLineWrapMode(1 if text.lineWrapMode() == 0 else 0)

# 有新内容则进行更新
obj.repaint()

# CSS格式的样式设置
setStyleSheet(css);
bt.setStyleSheet('border: 1px solid black; padding: 10px; font-size: 24px')

3 基础布局

3.1 盒子

QHBoxLayout # 水平
QVBoxLayout # 垂直

# 设置布局规则并应用布局
layout = QVBoxLayout()
window.setLayout(layout)

# 添加控件到布局器中
layout.addWidget(obj)
# 添加一个伸缩器,挤压空间,num是与其他伸缩器的比例
layout.addStretch([num])

# 布局嵌套
layout.addWidget(layout)

3.2 网格

# 网格布局,九宫格布局
QGridLayout

# 添加控件到布局器中(第几行第几列)
layout.addWidget(obj,row,col)
# 添加布局器到布局器中
layout.addLayout(bt)

3.3 表单

# 表单
QFormLayout

# 添加控件在同一行
layout.addRow(obj_1 , obj_2 , ...)

3.4 抽屉

# 控件抽屉
stacked_layout = QStackedLayout()
# 界面抽屉
stacked_widget = QStackWidget()


# 设置抽屉显示(默认为0)
stack.setCurrentIndex(0)
# 添加控件入屉
stacked_layout.addChildLayout(init_layout)
stacked_widget.addWidget(init_layout)

3.5 布局属性

# 添加部件,alianment对齐方式
Box.addWidget(layout,alignment=Qt.AlignCenter)
# 属性:Qt.AlignTop,QTabWidget.AlignBottom,QTabWidget.AlignLeft,Qt.AlignRight,Qt.AlignHCenter,Qt.AlignBottom

4 顶端栏

4.1 顶端栏

QMenuBar

# 设置菜单栏并加到栏目选项内。(不能分开)
menu = self.menuBar().addMenu("&name")
# 添加菜单选项
file_menu.addAction(name)

4.2 状态栏

QStatuBar QToolBar

# QStatusBar
# 初始化状态栏
self.status = QStatusBar()
# 加入到窗口中
self.setStatusBar(self.status)

# QToolBar
# 初始化工具栏
self.status = QToolBar()
# 添加分割线
obj.addSeparator()

四、PyQt5.QtGui

1 图标

QAction

图标网

# 添加图标
window.setWindowIcon(QIcon("img.png"))
# 设置宽高
widget.setIconSzie(Qsize(w,h))

# QAction,用于菜单栏、工具栏或自定义快捷键的抽象动作行为。
QAction

2 字体

# QFont初始化字体类
font = QFont()

# QFontDatabase,提供了关于底层窗口系统中可用字体的信息。
QFontDatabase
# 设置字体,返回字体(type:QFontDatabase.FixedFont)
fixedfont = QFontDatabase.systemFont( type )

# 设置字大小
fixedfont.setPointSize(num)
# 设置字加粗
fixedfont.setBold(bool)

# 加到控件中
self.editor.setFont(fixedfont)

五、PyQt5.QtCore

1 信号与槽

信号与槽

# 连接
# 对象.信号.connect( 槽函数 ),绑定信号与槽
obj.signal.connect(slot)
# 发射信号触发槽(括号中填入槽函数参数,可多个)
obj.signal.emit(func_argv)

# slot 传参
lambda: self.func( a , b , ... )


# 信号
# 点击
clicked
# 触发器
triggered
# 当前文本值改变
currentTextChanged[str]
# 值改变
valueChanged


# 自定义信号
# 注:只作类变量(str,[dict],[list])
my_signal = pyqtSignal( str , .... )
# 然后绑定信号,发送信号
# 自定义信号案例
# 父类
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# 信号绑定的函数
def init_table_row(self,condition:Union[bool,list] = True):
data = global_behavior.keyword_query(condition)

def add_new_account(self):
self.add_child_win = AddNewAccount()
# 通过信号绑定函数
self.add_child_win.close_signal.connect(self.init_table_row)
self.add_child_win.show()

# 子类
class AddNewAccount(QWidget):
# 自定义信号名字
close_signal = pyqtSignal()

def add_new_account(self):
# 把信号发送回父类
self.close_signal.emit()

2 多线程

# 创建线程与使用
# 主函数
self.ui = MyThread()
self.ui.start()

# 线程类
class MyThread( QThread ):
def __init__(self):
super().__init__()
def run( self ):
# start
pass
# 多线程信号
# 主线程
# 主线程函数,信号值存入res中
def update_Text(self,res): pass
# 主函数绑定信号发送给类中什么函数,然后启动线程
self.attack = AttackThread()
# 绑定子线程接受信号函数
self.attack.receive_signal.connect(attack.receive_Signal)
# 绑定子线程发送给主线程的函数
self.attack.send_signal.connect(self.update_Text)
# 可以提前发送一个信号给子线程
self.attack.receive_signal.emit(para)
# 启动子线程,子线程运行run
self.attack.start()


# 子线程
class AttackThread(QThread):
# 初始化自定义信号和信号类型
receive_signal = pyqtSignal(list)
send_signal = pyqtSignal(str)
# 定义接受主线程的函数,信号值存入para中
def receive_Signal(self,para): pass

六、打包

窗口化应用程序作为单文件可执行文件:pyinstaller --onefile --windowed myfile.py


七、问题

1 QtWebEngineWidgets

安装QtWebEngineWidgets:

  1. pip install pyqt5==5.10.1
  2. pip install PyQtWebEngine

八、案例

二维码识别:简单二维码 复杂二维码

图形化界面:普通十五个项目