PyQt5的学习笔记

学习PyQt

因为喜欢

内容参考自 ARCHi的博客

一.面向对象的创建GUI

1.根据如下格式即可创建图形化界面

class Example(QWidget):
    # 上述可以继承自QWidget 与 QMainWindow,分别表示其是控件或者是主窗口
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(300, 300, 300, 200)
        self.setWindowTitle('Sample')
        self.setWindowIcon(QIcon('icon.jpg'))   #设置Icon
        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())   # 进入主循环

2.添加按钮以及连接槽与信号

    btn = QPushButton('Quit', self)
    btn.clicked.connect(QCoreApplication.instance().quit)   
    # clicked信号发出后由 QCoreApplication的一个实例接受,退出
    # 经测试这里面可以使用 qApp.quit() 替换 QCoreApplication.instance().quit
    # 上述现象的原因:QApplication对象是可以通过全局变量qApp访问
    btn.resize(btn.sizeHint())  #sizeHint()用于获取一个合适的大小
    btn.move(0,0)

3.移动窗口使其居中


    def __init__:
        ...
        self.center()   #调用center以居中
        ...

    def center(self):
        # 居中
        qr = self.frameGeometry()  # 获得与主窗口的特定矩形,含框架
        cp = QDesktopWidget().availableGeometry().center()  # 计算屏幕中心位置
        qr.moveCenter(cp)  # 获得的矩形的中心移动到屏幕中心位置
        self.move(qr.topLeft())  # 将应用窗口的左上方移动到qr矩形的左上方

4.重载closeEvent() 以实现复杂退出动作

    def closeEvent(self, event):
        reply = QMessageBox.question(self, 'Message', "Are you sure to quit?",
                                     QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

PyQt5的学习笔记_第1张图片

二、菜单与工具箱

1.菜单按钮

# 定义一个用来实现退出的动作
    exitAction = QAction('&Exit', self) #定义了一个抽象动作,可以在第一个参数里面添加上QIcon
    exitAction.setShortcut('Ctrl+Q')    #定义快捷键
    exitAction.setStatusTip('Exit application') #定义StatusBar上面显示的信息
    exitAction.triggered.connect(qApp.quit) #其槽与 qApp.quit 相连接

    self.statusBar()    #添加statusBar以显示状态

    # 创建菜单栏并添加菜单
    menuBar = self.menuBar()    #创建了菜单栏
    fileMenu.addAction(exitAction)  #将退出动作添加为新菜单的 Action

2.工具箱

    #或者可以加入到工具栏中去
    self.toolbar = self.addToolBar('Exit')
    self.toolbar.addAction(exitAction)
    #测试此处不使用self. 而只使用toolBar没有问题,虽然原因不清楚,但是感觉这样似乎是合理一点。

PyQt5的学习笔记_第2张图片

三.布局

1.绝对定位布局
感觉用处不大…略

2.箱式布局

    okButton = QPushButton('OK')
    okButton.clicked.connect(qApp.quit)
    canelButton = QPushButton('Cance')

    # '''
    # 这里建立了一个基于hbox与vbox的箱布局
    hbox = QHBoxLayout()
    vbox = QVBoxLayout()

    hbox.addStretch(1)  #增加了一个拉伸因子使得按钮被推到了窗口的右边
    hbox.addWidget(okButton)
    hbox.addWidget(canelButton)

    vbox.addStretch(1) #增加一个拉伸因子,使得按钮被推到了窗口的下面
    vbox.addLayout(hbox)

    self.setLayout(vbox)

PyQt5的学习笔记_第3张图片

3.网式布局

    grid = QGridLayout()
    self.setLayout(grid)
    names = ['Cls', 'Bck', '', 'Close',
             '7', '8', '9', '/',
            '4', '5', '6', '*',
             '1', '2', '3', '-',
            '0', '.', '=', '+']
    positons = [(i, j) for i in range(5) for j in range(4)]
    for positon, name in zip(positons, names):
        if (name == ''):
            continue
        button = QPushButton(name)
        print(positon,"    " ,*positon, type(positon), "   ", type(positon))
        grid.addWidget(button, *positon)    #此处关于 * positons 存疑!

PyQt5的学习笔记_第4张图片
4.文本审阅布局
其实就是可以跨行的grid

# 文本审阅布局??
    title = QLabel('Title')
    author = QLabel('Author')
    review = QLabel('Review')

    titleEdit = QLineEdit()
    authorEdit = QLineEdit()
    reviewEdit = QTextEdit()

    grid = QGridLayout()
    grid.setSpacing(10) # 设置组件之间的间距

    grid.addWidget(title, 1, 0)
    grid.addWidget(titleEdit, 1, 1)

    grid.addWidget(author, 2, 0)
    grid.addWidget(authorEdit, 2, 1)

    grid.addWidget(review, 3, 0, 5, 1)
    grid.addWidget(reviewEdit, 3, 1, 5, 1)  #跨了5行

PyQt5的学习笔记_第5张图片

四事件与信号

1.简单的例子

    # 信号与槽
    lcd = QLCDNumber(self)  # 显示lcd数字(类似于计算器上面的数字)
    sld = QSlider(Qt.Horizontal, self)  # sliderbar 滑动条

    vbox = QVBoxLayout()
    vbox.addWidget(lcd)
    vbox.addWidget(sld)
    self.setLayout(vbox)

    # 连接滑动块的valueChanged 信号与 lcd的display槽
    sld.valueChanged.connect(lcd.display)

PyQt5的学习笔记_第6张图片

2.通过 sender 获取信号发送者的信息

    self.label = QLabel('Hello')
    btn1 = QPushButton('Button 1')
    btn2 = QPushButton('Button 2')
    btn1.clicked.connect(self.buttonClicked)
    btn2.clicked.connect(self.buttonClicked)
    hbox = QHBoxLayout()
    hbox.addWidget(self.label)
    hbox.addStretch()
    hbox.addWidget(btn1)
    hbox.addWidget(btn2)
    vbox.addLayout(hbox)
    # vbox.addWidget(label)

def buttonClicked(self):
    sender = self.sender()  # sender立马存有信号发送者的信息
    self.label.setText(sender.text()+"  was pressed")

PyQt5的学习笔记_第7张图片

3.可以自己建立一个类用来发送信号,具体见代码

    ...
    self.c = Communicate()
    self.c.closeApp.connect(self.close)
    ...

class Communicate(QObject):
    closeApp = pyqtSignal()

def mousePressEvent(self, event):
    self.c.closeApp.emit()

四、对话框

1.简单的对话框:

    self.le = QLineEdit(self)
    vbox.addWidget(self.le)

def showDialog(self):
    text, ok = QInputDialog.getText(self, 'Input Dialog', 'Enter your name')
    # if ok:
    self.le.setText(text)   # 上面的 if 被注释了是因为发现其存在与否没有意义
    # !!!并不是这样,我发现如果我没有判断是不是点了 ok 的话,当我选择Cancel的时候就会
    #把之前lineEdit里面的内容删掉(不管我有没有在dialog里面输入)

PyQt5的学习笔记_第8张图片
PyQt5的学习笔记_第9张图片

五、简单插件

1.进度条
使用QProgressBar来显示进度条

    # 添加ProgressBar 与 timer
     # ProgressBar
    self.pbar = QProgressBar()
    vbox.addWidget(self.pbar)

    # Timer
    self.timer = QBasicTimer()
    self.step = 0
    self.btn1.clicked.connect(self.doAction)

def timerEvent(self, QTimerEvent):
    # 重写timerEvent 函数以根据set调整ProgressBar
    if self.step >= 100:
        self.timer.stop()
        self.btn1.setText('Finished')
        return
    self.step += 1
    self.pbar.setValue(self.step)

def doAction(self):
    # 这是按钮被点击之后触发的函数
    if self.timer.isActive():   # 按钮被点击时timer是否处于激活态
        self.timer.stop()   #显然是要暂停
        self.btn1.setText('Start')

    else:
        self.timer.start(100, self) # 非激活态被点击自然是希望开始计时啦
        self.btn1.setText('Stop')
        # 下面的操作使得当前进度结束后可以重新开始,在实际中用不上,但是学习时可以方便观察其哟行机制
        if self.step >= 100:
            self.step = 0
            self.btn1.setText('Start')
            self.timer.stop()
            self.pbar.setValue(0)

PyQt5的学习笔记_第10张图片
PyQt5的学习笔记_第11张图片
PyQt5的学习笔记_第12张图片


头文件

#! /usr/bin/python3
# coding = utf-8
# from PyQt5 import QtGui,QtCore,Qt
import sys
from PyQt5.QtCore import Qt,pyqtSignal,QSize,QRect,QMetaObject, QCoreApplication, pyqtSlot,QPropertyAnimation,QThread
from PyQt5.QtGui import QIcon, QFont, QPixmap, QPainter, QImage
from PyQt5.QtWidgets import QMainWindow, QApplication

import cv2
from PyQt5. import SIGNAL, time
from PyQt5 import QtCore

你可能感兴趣的:(学习笔记)