标签 python 下的文章

pyqt 介绍

qt 介绍

Qt 是一个著名的 C++ 库——并不只是一个 GUI 库。使用 Qt,在一定程序上你获得的是一个“一站式”的服务:不再需要研究 STL,不再需要 C++ 的string,因为Qt有它自己的 QString 等等。Qt 本身包含的模块也日益丰富, 一直有新模块和第三方模块加入进来。

QT中的信号与槽(Signal & Slot)机制是 Qt 编程的基础,也是 Qt 的一大创新,使得在 Qt 中处理界面各个组件的交互操作时变得更加直观和简单。

Qt的优点在于:

  • 跨平台实现
  • 广泛的库
  • 友好的API,友好的库实现代码
  • 提供偏向生产力的 Qt widgets 和 偏向交互的 Qt Quick,以及使用 html 的 Qt webengine

基于 Qt 开发的软件: KDE, WPS、YY语音、Skype、豆瓣电台、虾米音乐、淘宝助理、千牛、暴雪的战网客户端、VirtualBox、Opera、咪咕音乐、Google地图、Adobe Photoshop Album 等

嵌入式 Linux 上很多带界面软件也是基于 Qt 来编写的。

pyqt 介绍

PyQt实现了一个Python模块集。它有超过300类,将近6000个函数和方法。它是一个多平台的工具包,可以运行在所有主要操作系统上,包括UNIX,Windows和Mac。

为可用的类有很多,他们被分成几个模块。

  • QtCore模块包含核心的非GUI功能。该模块用于时间、文件和目录、各种数据类型、流、网址、MIME类型、线程或进程。
  • QtGui模块包含图形组件和相关的类,例如按钮、窗体、状态栏、工具栏、滚动条、位图、颜色、字体等。
  • QtNetwork模块包含了网络编程的类,这些类允许编写TCP/IP和UDP的客户端和服务器,他们使网络编程更简单,更轻便。
  • QtXml包含使用XML文件的类,这个模块提供了SAX和DOM API的实现。
  • QtSvg模块提供显示的SVG文件的类。可缩放矢量图形(SVG)是一种用于描述二维图形和图形应用程序的XML语言。
  • QtOpenGL模块使用OpenGL库渲染3D和2D图形,该模块能够无缝集成Qt的GUI库和OpenGL库。
  • QtSql模块提供用于数据库的类。

基于 qt 的 python 界面: pyqt, pyside 基于 qt 的界面:Tkinter, WxPython

- 阅读剩余部分 -

在 numpy 中,resize 是用来改变数组的元素个数,而 reshap 不改变元素个数,只是改变维度,比如说从一维变成二维。

import numpy as np
X=np.array([[1,2,3,4],
              [5,6,7,8],
              [9,10,11,12]])

X_new=np.resize(X,(3,3)) # do not change the original X
print("X:\n",X)  #original X
print("X_new:\n",X_new) # new X

>>
X:
 [[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
X_new:
 [[1 2 3]
 [4 5 6]
 [7 8 9]]
import numpy as np
X=np.array([1,2,3,4,5,6,7,8])

X_2=X.reshape((2,4)) #retuen a 2*4 2-dim array
X_3=X.reshape((2,2,2)) # retuen a 2*2*2 3-dim array

print("X:\n",X)
print("X_2:\n",X_2)
print("X_3:\n",X_3)

>>
X:
 [1 2 3 4 5 6 7 8]
X_2:
 [[1 2 3 4]
 [5 6 7 8]]
X_3:
 [[[1 2]
  [3 4]]

 [[5 6]
  [7 8]]]

参考: https://blog.csdn.net/qq_24193303/article/details/80965274
https://blog.csdn.net/DocStorm/article/details/58593682

安装

pip3 install onnxruntime --user 会报错找不到对应的版本。 python3 -m pip install --upgrade pip 更新 pip,结果报错 Permission denied: '/usr/bin/pip'。 python3 -m pip install --upgrade pip --user 成功更新 pip。 pip3 install onnxruntime --user 安装 onnxruntime.

使用

python3 import onnxruntime 报错 Illegal instruction (core dumped)。 gdb python3 r import onnxruntime 报错

Program received signal SIGILL, Illegal instruction.
0x0000007fa8ca5f54 in gotoblas_dynamic_init ()
   from /home/openailab/.local/lib/python3.6/site-packages/numpy/core/../../numpy.libs/libopenblasp-r0-32ff4d91.3.13.so

解决方法, export OPENBLAS_CORETYPE=ARMV8 然后再使用 python3 就可以了。问题就是 openblasp 在 cpu 检测的地方除了问题,所以明确告诉它 cpu 类型就可以了。

参考:

https://github.com/opencv/opencv-python/issues/485
https://github.com/numpy/numpy/issues/18131

1. np.array([127, 127, 127]) 生成一个一维数组 [127, 127, 127]。

参考: https://numpy.org/doc/stable/reference/generated/numpy.array.html

2. a = np.reshape(list(range(24)), (2, 3, 4)) reshape 的第二个参数是维度参数,比如这个是一个三维数组,行数 2 行,列数 3 行,每个单位 4 个元素。

参考: https://numpy.org/doc/stable/reference/generated /numpy.reshape.html?highlight=reshape#numpy.reshape

3. image = np.transpose(image, [2, 0, 1]) 矩阵转置,第二个参数是相应的维度变化。 原始的维度是 [0, 1, 2] 其他的都是需要转换的。比如这个 [2, 0, 1] 意思是 把 第三维的数据提取出来作为第一维的开头数据,第一维的数据提取出来放到第二维,第二维的数据放到第三维。

arr = np.arange(16)
matrix = arr.reshape(2, 2, 4)
print("matrix: ", matrix)

matrix_4 = matrix.transpose((2, 0, 1))
print("matrix 4: ", matrix_4)

输出结果为

matrix:  [ [ [ 0  1  2  3]
             [ 4  5  6  7] ]

           [ [ 8  9 10 11]
             [12 13 14 15] ] ]

matrix 4:  [ [ [ 0  4]
               [ 8 12]]

             [ [ 1  5]
               [ 9 13] ]

             [ [ 2  6]
               [10 14] ]

             [ [ 3  7]
               [11 15] ] ]

参考: https://blog.csdn.net/u012762410/article/details/78912667

4. np.expand_dims(a, axis) 第二个参数表示具体再那个地方增加一个维度。

import numpy as np

a = np.reshape(list(range(24)), (2, 3, 4))
a_new = np.expand_dims(a, axis=0)
print('a =', a)
print('a_new =', a_new)
print('a.shape = ', a.shape)
print('a_new.shape = ', a_new.shape)
a = [[[ 0  1  2  3]
      [ 4  5  6  7]
      [ 8  9 10 11]]

     [[12 13 14 15]
      [16 17 18 19]
      [20 21 22 23]]]

a_new = [[[[ 0  1  2  3]
           [ 4  5  6  7]
           [ 8  9 10 11]]

          [[12 13 14 15]
           [16 17 18 19]
           [20 21 22 23]]]]
a.shape =  (2, 3, 4)
a_new.shape =  (1, 2, 3, 4)
import numpy as np

a = np.reshape(list(range(24)), (2, 3, 4))
print('a =', a)
print('np.expand_dims(a, axis=1) =', np.expand_dims(a, axis=1))
print('np.expand_dims(a, axis=2) =', np.expand_dims(a, axis=2))
print('np.expand_dims(a, axis=3) =', np.expand_dims(a, axis=3))
print('a.shape = ', a.shape)
print('np.expand_dims(a, axis=1).shape =', np.expand_dims(a, axis=1).shape)
print('np.expand_dims(a, axis=2).shape =', np.expand_dims(a, axis=2).shape)
print('np.expand_dims(a, axis=3).shape =', np.expand_dims(a, axis=3).shape)
a = [[[ 0  1  2  3]
      [ 4  5  6  7]
      [ 8  9 10 11]]

     [[12 13 14 15]
      [16 17 18 19]
      [20 21 22 23]]]
np.expand_dims(a, axis=1) = [[[[ 0  1  2  3]
                               [ 4  5  6  7]
                               [ 8  9 10 11]]]

                             [[[12 13 14 15]
                               [16 17 18 19]
                               [20 21 22 23]]]]
np.expand_dims(a, axis=2) = [[[[ 0  1  2  3]]
                              [[ 4  5  6  7]]
                              [[ 8  9 10 11]]]

                             [[[12 13 14 15]]
                              [[16 17 18 19]]
                              [[20 21 22 23]]]]
np.expand_dims(a, axis=3) = [[[[ 0]
                               [ 1]
                               [ 2]
                               [ 3]]

                              [[ 4]
                               [ 5]
                               [ 6]
                               [ 7]]

                              [[ 8]
                               [ 9]
                               [10]
                               [11]]]

                             [[[12]
                               [13]
                               [14]
                               [15]]

                              [[16]
                               [17]
                               [18]
                               [19]]

                              [[20]
                               [21]
                               [22]
                               [23]]]]
a.shape =  (2, 3, 4)
np.expand_dims(a, axis=1).shape = (2, 1, 3, 4)
np.expand_dims(a, axis=2).shape = (2, 3, 1, 4)
np.expand_dims(a, axis=3).shape = (2, 3, 4, 1)

参考: https://blog.csdn.net/weixin_41560402/article/details/105289015

5. .astype(np.float32) 转换数据类型。

参考: https://blog.csdn.net/qq_34638161/article/details/102853276

6. np.concatenate() 对数列或者矩阵进行合并。

import numpy as np
a=[1,2,3]
b=[4,5,6]
np.concatenate((a,b),axis=0)
array([1, 2, 3, 4, 5, 6])

参考: https://www.jianshu.com/p/a094a954ff61

7. numpy 和 list 互转

numpy -> list: array.tolist() list -> numpy: numpy.array(list) 参考: https://www.cnblogs.com/WMT-Azura/p/11138084.html

参考数目: https://www.runoob.com/numpy/numpy-array-manipulation.html https://numpy.org/doc/stable/user/c-info.html https://numpy.org.cn/article/advanced/numpy_exercises_for_data_analysis.html#numpy%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E9%97%AE%E7%AD%94

1. 从 二进制 pcm 文件中读取数据,并转化位想要的矩阵数组

    with open(audioPath, 'rb') as f:
        audioData = np.fromfile(f, dtype = np.uint16)
    audioData.shape = -1, 8

转换的音频数据是 不确定行,8列数组。

2. 把矩阵转置,以单声道数据为行。

    audioData = audioData.T

转换为 8行的二维数组,每一行就是一个声道的数据。

3. 抽取一个通道的数据。

    ch1 = audioData[4]

4. 把这个通道的数据写入二进制文件

    ch1.tofile("./audio/ch1.pcm")

参考: https://blog.51cto.com/feature09/2316652 https://blog.csdn.net/Tourior/article/details/110791039 https://blog.csdn.net/kebu12345678/article/details/54837245 https://numpy.org/doc/stable/reference/generated/numpy.fromfile.html#:~:text=numpy.fromfile.%20%C2%B6.%20numpy.fromfile%28file%2C%20dtype%3Dfloat%2C%20count%3D-1%2C%20sep%3D%27%27%2C%20offset%3D0%29%20%C2%B6.,tofile%20method%20can%20be%20read%20using%20this%20function. https://www.cnblogs.com/peixu/p/7991715.html https://blog.csdn.net/botao_li/article/details/104378469 https://www.cnblogs.com/noluye/p/11224137.html

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/