1. 安装见
https://www.cnblogs.com/ramlife/p/14096103.html
http://www.ramlife.org/2020/12/07/272.html  
2. 安装好后,import 一下,看看有没有问题。
python3
import PyQt5
exit()
3. 用 qtdesigner 做一个只有 label 的 ui,然后在 ui文件的 同目录下新建一个 py 文件。
#!/usr/bin/python3
import sys
from PyQt5.uic import loadUi
from PyQt5.QtWidgets import QMainWindow, QApplication
class MainWindow(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        loadUi("test.ui", self)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
这样就可以直接使用这个 ui 文件了。 这里面使用的 api 是 loadUi,而不是 loadUiType,所以不需要 setupUi 和 super。 所有 ui 界面里面的东西可以直接用 self 来调用了。比如 self.pushButton.clicked.connect(ShowString)
参考: https://blog.csdn.net/josephzhang1012/article/details/86696107
4. pyqt5 qml 简单例子
main.qml
import QtQuick.Window 2.2
import QtQuick 2.3
Window {
visible:true
width:600
height:400
color:"yellow"
title: "PyQt5 QML Window"
}
main.py
from PyQt5.QtQml import QQmlApplicationEngine
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QIcon
import sys
def runQML():
    app =QApplication(sys.argv)
    engine = QQmlApplicationEngine()
    app.setWindowIcon(QIcon("icon.png"))
    engine.load('main.qml')
    if not engine.rootObjects():
        return -1
    return app.exec_()
if __name__ == "__main__":
    sys.exit(runQML())
执行 main.py,就可以出现窗口了。
参考: https://codeloop.org/how-to-create-window-in-pyqt5-qtquick/
5. 信号与槽
from PyQt5.QtCore import QObject , pyqtSignal
class CustSignal(QObject):
    #声明无参数的信号
    signal1 = pyqtSignal()
    #声明带一个int类型参数的信号
    signal2 = pyqtSignal(int)
    #声明带int和str类型参数的信号
    signal3 = pyqtSignal(int,str)
    #声明带一个列表类型参数的信号
    signal4 = pyqtSignal(list)
    #声明带一个字典类型参数的信号
    signal5 = pyqtSignal(dict)
    #声明一个多重载版本的信号,包括带int和str类型参数的信号和带str类型参数的信号
    signal6 = pyqtSignal([int,str], [str])
    def __init__(self,parent=None):
        super(CustSignal,self).__init__(parent)
        #将信号连接到指定槽函数
        self.signal1.connect(self.signalCall1)
        self.signal2.connect(self.signalCall2)
        self.signal3.connect(self.signalCall3)
        self.signal4.connect(self.signalCall4)
        self.signal5.connect(self.signalCall5)
        self.signal6[int,str].connect(self.signalCall6)
        self.signal6[str].connect(self.signalCall6OverLoad)
        #发射信号
        self.signal1.emit()
        self.signal2.emit(1)
        self.signal3.emit(1,"text")
        self.signal4.emit([1,2,3,4])
        self.signal5.emit({"name":"wangwu","age":"25"})
        self.signal6[int,str].emit(1,"text")
        self.signal6[str].emit("text")
    def signalCall1(self):
        print("signal1 emit")
    def signalCall2(self,val):
        print("signal2 emit,value:",val)
    def signalCall3(self,val,text):
        print("signal3 emit,value:",val,text)
    def signalCall4(self,val):
        print("signal4 emit,value:",val)
    def signalCall5(self,val):
        print("signal5 emit,value:",val)
    def signalCall6(self,val,text):
        print("signal6 emit,value:",val,text)
    def signalCall6OverLoad(self,val):
        print("signal6 overload emit,value:",val)
if __name__ == '__main__':  
    custSignal = CustSignal()
参考: https://www.cnblogs.com/XJT2018/p/10222981.html https://blog.csdn.net/qq_38463737/article/details/107806432
6. button 设置样式表
    self.mBtnRecord.setStyleSheet("QPushButton{border-image: url(./assets/ico-常规背景.svg)} \
        QPushButton:hover{border-image: url(./assets/ico-选中后背景.svg)} \
        QPushButton:checked{border-image: url(./assets/ico-保持背景.svg)} \
        QPushButton:pressed{border-image: url(./assets/ico-点击背景.svg)} \
        QPushButton:disabled{border-image: url(./assets/ico-不可用背景.svg)}")
参考: https://blog.csdn.net/jays_/article/details/83785898 https://blog.csdn.net/weixin_47142322/article/details/105976861 https://www.cnblogs.com/xj626852095/p/3648119.html https://www.cnblogs.com/aheng123/p/5630761.html
7. button 设置持续按下
        self.mBtnRecord.setCheckable(True)
        self.mBtnRecord.setChecked(False)
检查按钮按下的情况
        if self.mBtnRecord.isChecked() is False:
            ...
        else:
            ...
参考: https://blog.csdn.net/qiangzi4646/article/details/80135120 https://www.cnblogs.com/lomper/p/4249575.html
8. button 按下换图标:
self.mBtnSpeed.setIcon(QIcon('./assets/ico-' + "变速" + '.svg'))
类似于这样来设置新图标就可以了。
9. timer
参考: https://www.cnblogs.com/liming19680104/p/10663968.html https://www.jianshu.com/p/74ea98e77114
参考书目: 《QmlBook》In Chinese https://cwc1987.gitbooks.io/qmlbook-in-chinese/content/ QmlBook http://qmlbook.github.io/index.html PyQt5 基本教學 (1) 安裝 PyQt5,印出 Hello World! https://clay-atlas.com/blog/2019/08/26/python-chinese-pyqt5-tutorial-install/