pyqt学习笔记二

又到了更新的时候,pyqt写软件还没有弄好,但是这周也不能算是完全没有进展的一周。下面就来复盘一下学到的pyqt基本知识

首先是所有知识系统的学习方法,按先后顺序可以看作是:控件的特性 控件的样式 资源的加载 控件的布局 事件的信号 动画特效 界面跳转 设计工具使用 额外(网络,多线程,数据库)

上面的结构基本上和我学习网页知识时候差不多,不过当时学习网页知识时候水平太低,撸的代码还是太少了,现在也都忘得差不多了。

复盘目标:信号槽机制 事件处理机制 定时器 vscode里面用户代码片段和自动补全设置

参数处理方式(self,*args,kwargvs)

关于事件处理机制我当然说不行,贴两个链接看完。

https://blog.****.net/qq_29344757/article/details/77994016

https://www.jianshu.com/p/48f007c2de09

信号槽机制:

信号槽机制(事件机制)是处理信号进行各类控件之间通信的核心机制

信号:当一个控件的状态发生改变时,向外界发出的信息。例如QPushButton1.pressed

信号可以是内置的也可以是自定义的

槽:一个执行某些操作的函数/方法,不同的控件里面有内置的槽函数,也可以自定义槽函数

信号与槽的链接通过object信号.connect(槽函数)来连接,一个信号可以连接多个槽函数,一个槽函数也可以监听多个信号。

一个简单的例子:

# -*-coding:utf-8 -*-
import io
import sys
# 改变标准输出的默认编码
sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='utf8')
from PyQt5.Qt import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

class App(QApplication):
    def notify(self, recevier, evt):
        if recevier.inherits("QPushButton") and evt.type() == QEvent.MouseButtonPress:
            print(recevier, evt)
        return super().notify(recevier, evt)
  
class Btn(QPushButton):
    def event(self, evt):
        if evt.type() == QEvent.MouseButtonPress:
           print(evt)
        return super().event(evt)
    def mousePressEvent(self, *args, **kwargs):
        print("鼠标被按下..")

if __name__ == '__main__':
# 创建一个Qapplication类实例
    app= App(sys.argv)
    # 创建一个窗口
    w=QWidget()
    w.resize(300,150)
    w.move(300,300)
    w.setWindowTitle("事件代码机制")


    btn=Btn(w)
    btn.setText("按钮")
    def cao():
        print("按钮被按下了")
    btn.pressed.connect(cao)
    w.show()
    # 进入程序的主循环,并通过exit函数安全结束
    sys.exit(app.exec_())

上面代码中首先建立了pushbutton和cao函数之间的联系来验证信号与槽机制,然后在通过重写QApplication类里的notify函数和Qbushbutton类里的event函数来进行事件处理机制的验证使用。

关键的学习点在于:

1.对于面向对象方法,处理函数和封装的办法,主要是通过继承和重写机制,这就需要对于控件内部的函数具有极高的了解。

2.对于python基础要求掌握,重写QApplication里面notify函数的参数有哪些,使用recevier.inherits()和evt.type()进行事件的筛选,还有如何使用super()来返回原来需要返回的参数, def mousePressEvent(self, *args, **kwargs) 里面,当函数的参数不确定时,可以使用*args 和**kwargs,*args 没有key值,**kwargs有key值。

最后结果如图:

pyqt学习笔记二

定时器:

定时器是通过软件来进行定时,看起来有点像多线程但又有区别,关于两者的区别我找了一篇文章,这里的定时器和单片机里的定时器应该不是一个东西,单片机中的定时器是硬件控制,和晶振的频率息息相关,而这里不一样:

https://blog.****.net/wangweitingaabbcc/article/details/6723606

定时器的使用;

# -*-coding:utf-8 -*-
import io
import sys
# 改变标准输出的默认编码
sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='utf8')
from PyQt5.Qt import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

class MyObject(QObject):
    def timerEvent(self, evt):
        print(evt, "1")

class MyLabel(QLabel):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setText("10")
        self.move(100, 100)
        self.setStyleSheet("font-size: 22px;")

    def setSec(self, sec):
        self.setText(str(sec))

    def startMyTimer(self, ms):
        self.timer_id = self.startTimer(ms)    

    def timerEvent(self, *args, **kwargs):
        print("xx")
        # 1. 获取当前的标签的内容
        current_sec = int(self.text())
        current_sec -= 1
        self.setText(str(current_sec))

        if current_sec == 0:
            print("停止")
            self.killTimer(self.timer_id)

# class MyWidget(QWidget):
#     def timerEvent(self, *args, **kwargs):
#         current_w = self.width()
#         current_h = self.height()
#         self.resize(current_w + 10, current_h + 10)
# 实现窗口大小控制功能

if __name__ == '__main__':
    # 创建一个Qapplication类实例
    app=QApplication(sys.argv)
    # 创建一个窗口
    w=QWidget()
    w.resize(300,150)
    w.move(300,300)
    w.setWindowTitle("定时器使用")
    label=MyLabel(w)
    label.startTimer(1000)
    w.startTimer(1000)
    w.show()
    # 进入程序的主循环,并通过exit函数安全结束
    sys.exit(app.exec_())
    

定时器和多线程比起来还是比较简单,毕竟没有太多花里胡哨的东西,使用得多的就两个函数,一个startTimer一个killTimer。上面代码的难点在于面向对象的封装,例如重写QLabel时候要进行初始化,因为要用到别的paint事件来画图,中间还简单的使用了一下qss,在设置函数时候留下可操作性很高,比如设置时间。上面代码实现了简单的一个从10到1的倒计时功能。

vscode相关:

使用vscode写代码还是不是特别好,对于智能补全功能要求高的时候尤其显现出来,首先是pyqt自动补全的设置需要在setting.json里面添加路径,关键在于对于某些事件的补全不完全,和相关函数里面的参数不显示,例如上面事件处理机制中的notify()参数就很难知道有什么。这导致我在调代码时候因为mousePressEvent写成MousePressEvent导致结果和预期不一样。然后就是用户*代码的设置了,这个到没什么,在首选项中添加就是了,只不过写的时候稍微麻烦一点。总结就是可能还是需要下载一个pycharm了。

上一篇:PyQt+socket实现远程操作服务器的方法示例


下一篇:PyQt完整入门教程