python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析


Posted in Python onMarch 08, 2020

PyQt5中信号与槽可以说是对事件处理机制的高级封装,如果说事件是用来创建窗口控件的,那么信号与槽就是用来对这个控件进行使用的,比如一个按钮,当我们使用按钮时,只关心clicked信号,至于这个按钮如何接受并处里鼠标点击事件,然后在发射这个信号,则不关心,但是如果要重载一个按钮,这时候就要关心了,比如可以改变它的行为:在鼠标按下时触发clicked信号,而不是释放时

PyQt5常见事件类型

pyqt是对Qt的封装,qt程序是事件驱动的,它的每个动作都有幕后某个事件所触发,Qt事件类型有很多,常见的如下

  • 键盘事件:按键的按下与松开
  • 鼠标事件:鼠标指针的移动,鼠标按键的按下与松开
  • 拖放事件:用鼠标进行拖放
  • 滚轮事件:鼠标滚轮滚动
  • 绘屏事件:重绘制屏幕的某些部分
  • 定时事件:定时器到时
  • 焦点事件:键盘焦点移动
  • 进入和离开事件:鼠标指针移入Widget内,或者移出
  • 移动事件:Widget的位置改变
  • 大小改变事件:widget的大小改变
  • 显示和隐藏事件:widget显示与隐藏
  • 窗口事件:窗口是否为当前窗口

还有一些常见的qt事件,比如Socket事件,剪切板事件,字体改变事件,布局改变事件

使用事件处理的方法

pyqt提供如下5中事件处理和过滤的方法(有弱到强),其中只有前两种方法使用最频繁

1 、重新实现事件函数

比如mousePressEvent(),keyPressEvent(),paintEvent(),这是最常规的事件处理方法

2 、重新实现QObject.event()

一般用在pyqt没有提供该事件的处理函数的情况下,即增加新事件时

3 、安装事件过滤器

如果对QObject调用installEventFilter,则相当于为这个QObject安装了一个事件过滤器,对于QObject的全部事件来说,它们都会先传递到事件过滤函数eventFilter中,在这个函数中,我们可以抛弃或者修改这些事件,比如对自己感兴趣的事件使用自定义的处理机制,对其他事件采用默认的事件处理机制,由于这中方法会调用installEventFilter的所有QObject的事件进行过滤,因此如果要过滤的事件比较多,则会降低程序的性能

4 、在QApplication中安装事件过滤器

这种方法比上一种更强大,QApplication的事件过滤器将捕获所有的QObject事件,而且第一个获得该事件,也就是说,在将事件发送给其他任何一个事件过滤器之前,都会发送给QApplication的事件过滤器

5 、重新实现QApplication的notify()方法

pyqt使用notify来分发事件,要想在任何事件处理器之前捕获事件,唯一的方法就是重新实现QApplication的notify(),在实践中,在调试才会用这中方法

PyQt5信号与槽事件处理经典案例

import sys
from PyQt5.QtCore import (QEvent, QTimer, Qt)
from PyQt5.QtWidgets import (QApplication, QMenu, QWidget)
from PyQt5.QtGui import QPainter
class Widget(QWidget):
  def __init__(self, parent=None):
    super(Widget, self).__init__(parent)
    #初始化数据
    #鼠标双击False
    self.justDoubleClicked = False
    #按键,输出文本,提示消息为空
    self.key = ""
    self.text = ""
    self.message = ""
    #设置窗口初始大小与位置
    self.resize(400, 300)
    self.move(100, 100)
    #设置标题
    self.setWindowTitle("Events")
    #定时器1秒后执行槽函数
    QTimer.singleShot(1000, self.giveHelp)
    # 避免窗口大小重绘事件的影响,可以把参数0改变成3000(3秒),然后在运行,就可以明白这行代码的意思。
  def giveHelp(self):
    self.text = "请点击这里触发追踪鼠标功能"
    # 重绘事件,也就是触发paintEvent函数。
    self.update()
  '''重新实现关闭事件'''
  def closeEvent(self, event):
    print("Closed")
  '''重新实现上下文菜单事件'''
  def contextMenuEvent(self, event):
    #实例化菜单,添加子菜单one two并附加快捷键功能,关联槽函数
    menu = QMenu(self)
    oneAction = menu.addAction("&One")
    twoAction = menu.addAction("&Two")
    oneAction.triggered.connect(self.one)
    twoAction.triggered.connect(self.two)
    #如果message为空,执行
    if not self.message:
      #在菜单中添加一条分割线
      menu.addSeparator()
      #添加自菜单three,关联槽函数
      threeAction = menu.addAction("Thre&e")
      threeAction.triggered.connect(self.three)
    #菜单栏出现在鼠标的位置
    menu.exec_(event.globalPos())
  '''上下文菜单槽函数'''
  def one(self):
    self.message = "Menu option One"
    self.update()
  def two(self):
    self.message = "Menu option Two"
    self.update()
  def three(self):
    self.message = "Menu option Three"
    self.update()
  '''重新实现绘制事件'''
  def paintEvent(self, event):
    text = self.text
    i = text.find("\n\n")
    if i >= 0:
      text = text[0:i]
    # 若触发了键盘按钮,则在文本信息中记录这个按钮信息。
    if self.key:
      text += "\n\n你按下了: {0}".format(self.key)
    painter = QPainter(self)
    painter.setRenderHint(QPainter.TextAntialiasing)
    # 绘制信息文本的内容
    painter.drawText(self.rect(), Qt.AlignCenter, text)
    # 若消息文本存在则在底部居中绘制消息,5秒钟后清空消息文本并重绘。
    if self.message:
      #显示给定坐标处的文本,坐标,对齐方式。文本内容
      painter.drawText(self.rect(), Qt.AlignBottom | Qt.AlignHCenter,
               self.message)
      #5秒钟后触发清空信息的函数,并重新绘制事件
      QTimer.singleShot(5000, self.clearMessage)
      QTimer.singleShot(5000, self.update)
  '''清空消息文本的槽函数'''
  def clearMessage(self):
    self.message = ""
  '''重新实现调整窗口大小事件'''
  def resizeEvent(self, event):
    self.text = "调整窗口大小为: QSize({0}, {1})".format(
      event.size().width(), event.size().height())
    self.update()
  '''重新实现鼠标释放事件'''
  def mouseReleaseEvent(self, event):
    # 若鼠标释放为双击释放,则不跟踪鼠标移动
    if self.justDoubleClicked:
      self.justDoubleClicked = False
    # 若鼠标释放为单击释放,则需要改变跟踪功能的状态,如果开启跟踪功能的话就跟踪,不开启跟踪功能就不跟踪
    else:
      # 单击鼠标
      self.setMouseTracking(not self.hasMouseTracking())
      if self.hasMouseTracking():
        self.text = "开启鼠标跟踪功能.\n" + \
              "请移动一下鼠标!\n" + \
              "单击鼠标可以关闭这个功能"
      else:
        self.text = "关闭鼠标跟踪功能.\n" + \
              "单击鼠标可以开启这个功能"
      self.update()
  '''重新实现鼠标移动事件'''
  def mouseMoveEvent(self, event):
    #如果没有鼠标双击,执行
    if not self.justDoubleClicked:
      # 窗口坐标转换为屏幕坐标
      globalPos = self.mapToGlobal(event.pos())
      self.text = """鼠标位置:
      窗口坐标为:QPoint({0}, {1}) 
      屏幕坐标为:QPoint({2}, {3}) """.format(event.pos().x(), event.pos().y(), globalPos.x(), globalPos.y())
      self.update()
  '''重新实现鼠标双击事件'''
  def mouseDoubleClickEvent(self, event):
    self.justDoubleClicked = True
    self.text = "你双击了鼠标"
    self.update()
  '''重新实现键盘按下事件'''
  def keyPressEvent(self, event):
    self.key = ""
    if event.key() == Qt.Key_Home:
      self.key = "Home"
    elif event.key() == Qt.Key_End:
      self.key = "End"
    elif event.key() == Qt.Key_PageUp:
      if event.modifiers() & Qt.ControlModifier:
        self.key = "Ctrl+PageUp"
      else:
        self.key = "PageUp"
    elif event.key() == Qt.Key_PageDown:
      if event.modifiers() & Qt.ControlModifier:
        self.key = "Ctrl+PageDown"
      else:
        self.key = "PageDown"
    elif Qt.Key_A <= event.key() <= Qt.Key_Z:
      if event.modifiers() & Qt.ShiftModifier:
        self.key = "Shift+"
      self.key += event.text()
    #如果key有字符,不为空,则绘制字符
    if self.key:
      self.key = self.key
      self.update()
    #否则就继续监视这个事件
    else:
      QWidget.keyPressEvent(self, event)
  '''重新实现其他事件,适用于PyQt没有提供该事件的处理函数的情况,Tab键由于涉及焦点切换,不会传递给keyPressEvent,因此,需要在这里重新定义。'''
  def event(self, event):
    #如果有按键按下,并且按键是tab键
    if (event.type() == QEvent.KeyPress and
          event.key() == Qt.Key_Tab):
      self.key = "在event()中捕获Tab键"
      self.update()
      return True
    return QWidget.event(self, event)
if __name__ == "__main__":
  app = QApplication(sys.argv)
  form = Widget()
  form.show()
  app.exec_()

代码解析

首先是类的建立,建立text和message两个变量,使用painEvent函数把他们输出到窗口中

update函数的作用是更新窗口,由于窗口更新过程中会触发一次paineEvent函数(paintEvent是窗口基类QWidget的内部函数),因此在本例中,update函数的作用等同于paintEvent函数

import sys
from PyQt5.QtCore import (QEvent, QTimer, Qt)
from PyQt5.QtWidgets import (QApplication, QMenu, QWidget)
from PyQt5.QtGui import QPainter
class Widget(QWidget):
  def __init__(self, parent=None):
    super(Widget, self).__init__(parent)
    #初始化数据
    #鼠标双击False
    self.justDoubleClicked = False
    #按键,输出文本,提示消息为空
    self.key = ""
    self.text = ""
    self.message = ""
    #设置窗口初始大小与位置
    self.resize(400, 300)
    self.move(100, 100)
    #设置标题
    self.setWindowTitle("Events")
    #定时器1秒后执行槽函数
    QTimer.singleShot(1000, self.giveHelp)
    # 避免窗口大小重绘事件的影响,可以把参数0改变成3000(3秒),然后在运行,就可以明白这行代码的意思。
  def giveHelp(self):
    self.text = "请点击这里触发追踪鼠标功能"
    # 重绘事件,也就是触发paintEvent函数。
    self.update()

初始化运行结果如下

python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析

然后是重新实现窗口关闭事件与上下文菜单事件,主要影响message标量的结果,paintEvent负责把这个变量在窗口底部输出

'''重新实现关闭事件'''
  def closeEvent(self, event):
    print("Closed")
  '''重新实现上下文菜单事件'''
  def contextMenuEvent(self, event):
    #实例化菜单,添加子菜单one two并附加快捷键功能,关联槽函数
    menu = QMenu(self)
    oneAction = menu.addAction("&One")
    twoAction = menu.addAction("&Two")
    oneAction.triggered.connect(self.one)
    twoAction.triggered.connect(self.two)
    #如果message为空,执行
    if not self.message:
      #在菜单中添加一条分割线
      menu.addSeparator()
      #添加自菜单three,关联槽函数
      threeAction = menu.addAction("Thre&e")
      threeAction.triggered.connect(self.three)
    #菜单栏出现在鼠标的位置
    menu.exec_(event.globalPos())
  '''上下文菜单槽函数'''
  def one(self):
    self.message = "Menu option One"
    self.update()
  def two(self):
    self.message = "Menu option Two"
    self.update()
  def three(self):
    self.message = "Menu option Three"
    self.update()

python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析

绘制事件是代码的核心事件,它的作用是时刻跟随text和message这两个变量的信息,并把text内容绘制到窗口的中部,把message的内容绘制到窗口的底部

'''重新实现绘制事件'''
  def paintEvent(self, event):
    text = self.text
    i = text.find("\n\n")
    if i >= 0:
      text = text[0:i]
    # 若触发了键盘按钮,则在文本信息中记录这个按钮信息。
    if self.key:
      text += "\n\n你按下了: {0}".format(self.key)
    painter = QPainter(self)
    painter.setRenderHint(QPainter.TextAntialiasing)
    # 绘制信息文本的内容
    painter.drawText(self.rect(), Qt.AlignCenter, text)
    # 若消息文本存在则在底部居中绘制消息,5秒钟后清空消息文本并重绘。
    if self.message:
      #显示给定坐标处的文本,坐标,对齐方式。文本内容
      painter.drawText(self.rect(), Qt.AlignBottom | Qt.AlignHCenter,
               self.message)
      #5秒钟后触发清空信息的函数,并重新绘制事件
      QTimer.singleShot(5000, self.clearMessage)
      QTimer.singleShot(5000, self.update)
  '''清空消息文本的槽函数'''
  def clearMessage(self):
    self.message = ""

接下来是调整窗口大小事件

'''重新实现调整窗口大小事件'''
  def resizeEvent(self, event):
    self.text = "调整窗口大小为: QSize({0}, {1})".format(
      event.size().width(), event.size().height())
    self.update()

python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析

实现鼠标释放事件,若为双击释放,则不跟随鼠标移动,若为单击释放,则需要跟随鼠标移动状态进行更改,如果开启跟踪功能就跟踪,否则就不跟综

'''重新实现鼠标释放事件'''
  def mouseReleaseEvent(self, event):
    # 若鼠标释放为双击释放,则不跟踪鼠标移动
    if self.justDoubleClicked:
      self.justDoubleClicked = False
    # 若鼠标释放为单击释放,则需要改变跟踪功能的状态,如果开启跟踪功能的话就跟踪,不开启跟踪功能就不跟踪
    else:
      # 单击鼠标
      self.setMouseTracking(not self.hasMouseTracking())
      if self.hasMouseTracking():
        self.text = "开启鼠标跟踪功能.\n" + \
              "请移动一下鼠标!\n" + \
              "单击鼠标可以关闭这个功能"
      else:
        self.text = "关闭鼠标跟踪功能.\n" + \
              "单击鼠标可以开启这个功能"
      self.update()

python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析

python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析

python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析

实现鼠标移动事件

'''重新实现鼠标移动事件'''
  def mouseMoveEvent(self, event):
    #如果没有鼠标双击,执行
    if not self.justDoubleClicked:
      # 窗口坐标转换为屏幕坐标
      globalPos = self.mapToGlobal(event.pos())
      self.text = """鼠标位置:
      窗口坐标为:QPoint({0}, {1}) 
      屏幕坐标为:QPoint({2}, {3}) """.format(event.pos().x(), event.pos().y(), globalPos.x(), globalPos.y())
      self.update()
  '''重新实现鼠标双击事件'''
  def mouseDoubleClickEvent(self, event):
    self.justDoubleClicked = True
    self.text = "你双击了鼠标"
    self.update()

python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析

实现键盘按下事件

'''重新实现键盘按下事件'''
  def keyPressEvent(self, event):
    self.key = ""
    if event.key() == Qt.Key_Home:
      self.key = "Home"
    elif event.key() == Qt.Key_End:
      self.key = "End"
    elif event.key() == Qt.Key_PageUp:
      if event.modifiers() & Qt.ControlModifier:
        self.key = "Ctrl+PageUp"
      else:
        self.key = "PageUp"
    elif event.key() == Qt.Key_PageDown:
      if event.modifiers() & Qt.ControlModifier:
        self.key = "Ctrl+PageDown"
      else:
        self.key = "PageDown"
    elif Qt.Key_A <= event.key() <= Qt.Key_Z:
      if event.modifiers() & Qt.ShiftModifier:
        self.key = "Shift+"
      self.key += event.text()
    #如果key有字符,不为空,则绘制字符
    if self.key:
      self.key = self.key
      self.update()
    #否则就继续监视这个事件
    else:
      QWidget.keyPressEvent(self, event)

python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析

重载tab键

'''重新实现其他事件,适用于PyQt没有提供该事件的处理函数的情况,Tab键由于涉及焦点切换,不会传递给keyPressEvent,因此,需要在这里重新定义。'''
  def event(self, event):
    #如果有按键按下,并且按键是tab键
    if (event.type() == QEvent.KeyPress and
          event.key() == Qt.Key_Tab):
      self.key = "在event()中捕获Tab键"
      self.update()
      return True
    return QWidget.event(self, event)

python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析

过滤器的使用

import sys
from PyQt5 import Qt
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class EventFilter(QDialog):
  def __init__( self, parent=None ):
    super(EventFilter, self).__init__(parent)
    self.setWindowTitle('事件过滤器')
    #实例化并设置四个标签文本
    self.label1 = QLabel('请点击')
    self.label2 = QLabel('请点击')
    self.label3 = QLabel('请点击')
    self.labelState = QLabel('test')
    #加载三个图片
    self.image1 = QImage('images\cartoon1.ico')
    self.image2 = QImage('images\cartoon2.ico')
    self.image3 = QImage('images\cartoon3.ico')
    self.width = 600
    self.height = 300
    #设置初始大小
    self.resize(self.width, self.height)
    #使用事假过滤器
    self.label1.installEventFilter(self)
    self.label2.installEventFilter(self)
    self.label3.installEventFilter(self)
    #设置窗口布局方式并添加控件
    layoyt = QGridLayout(self)
    layoyt.addWidget(self.label1, 500, 0)
    layoyt.addWidget(self.label2, 500, 1)
    layoyt.addWidget(self.label3, 500, 2)
    layoyt.addWidget(self.labelState, 600, 1)
  def eventFilter( self, watched, event ):
    #对事件一的处理过滤机制
    if watched == self.label1:
      if event.type() == QEvent.MouseButtonPress:
        mouseEvent = QMouseEvent(event)
        if mouseEvent.buttons() == Qt.LeftButton:
          self.labelState.setText('按下鼠标左键')
        elif mouseEvent.buttons() == Qt.MidButton:
          self.labelState.setText('按下鼠标中间键')
        elif mouseEvent.buttons() == Qt.RightButton:
          self.labelState.setText('按下鼠标右键')
        #转换图片大小
        transform=QTransform()
        transform.scale(0.5,0.5)
        tmp=self.image1.transformed(transform)
        self.label1.setPixmap(QPixmap.fromImage(tmp))
      if event.type()==QEvent.MouseButtonRelease:
        self.labelState.setText('释放鼠标按键')
        self.label1.setPixmap(QPixmap.fromImage(self.image1))
    return QDialog.eventFilter(self,watched,event)
if __name__ == '__main__':
  app=QApplication(sys.argv)
  dialog=EventFilter()
  app.installEventFilter(dialog)
  dialog.show()
  app.exec_()

运行效果如图

python GUI库图形界面开发之PyQt5信号与槽事件处理机制详细介绍与实例解析

代码解析

下面的代码意思是这个过滤器只对label1的事件进行处理,并且只处理它的鼠标按下事件和鼠标释放事件

def eventFilter( self, watched, event ):
    #对事件一的处理过滤机制
    if watched == self.label1:
      if event.type() == QEvent.MouseButtonPress:
        mouseEvent = QMouseEvent(event)
        if mouseEvent.buttons() == Qt.LeftButton:
          self.labelState.setText('按下鼠标左键')
        elif mouseEvent.buttons() == Qt.MidButton:
          self.labelState.setText('按下鼠标中间键')
        elif mouseEvent.buttons() == Qt.RightButton:
          self.labelState.setText('按下鼠标右键')
        #转换图片大小
        transform=QTransform()
        transform.scale(0.5,0.5)
        tmp=self.image1.transformed(transform)
        self.label1.setPixmap(QPixmap.fromImage(tmp))
      if event.type()==QEvent.MouseButtonRelease:
        self.labelState.setText('释放鼠标按键')
        self.label1.setPixmap(QPixmap.fromImage(self.image1))
    #对于其他的情况会返回系统默认的处理方法
    return QDialog.eventFilter(self,watched,event)

一下四行代码的意思是如果按下这个鼠标键,就会对label1装载的图片进行缩放一半

#转换图片大小
        transform=QTransform()
        transform.scale(0.5,0.5)
        tmp=self.image1.transformed(transform)
        self.label1.setPixmap(QPixmap.fromImage(tmp))

在QApplication中安装事件过滤器的使用也非常简单,只需要修改俩个地方

        #使用事件过滤器

        # self.label1.installEventFilter(self)

        # self.label2.installEventFilter(self)

        # self.label3.installEventFilter(self)

if __name__ == '__main__':
  app=QApplication(sys.argv)
  dialog=EventFilter()
  app.installEventFilter(dialog)
  dialog.show()
  app.exec_()

运行效果是一样的

好了,本文主要讲解了PyQt5信号与槽事件处理机制详细介绍与实例解析,更多关于PyQt5信号与槽的知识请查看下面的相关链接

Python 相关文章推荐
详解python的webrtc库实现语音端点检测
May 31 Python
Python使用Selenium+BeautifulSoup爬取淘宝搜索页
Feb 24 Python
Python中函数参数调用方式分析
Aug 09 Python
python 实现创建文件夹和创建日志文件的方法
Jul 07 Python
python将类似json的数据存储到MySQL中的实例
Jul 12 Python
对python 树状嵌套结构的实现思路详解
Aug 09 Python
Tensorflow 多线程与多进程数据加载实例
Feb 05 Python
Python爬取酷狗MP3音频的步骤
Feb 26 Python
Pyhton模块和包相关知识总结
May 12 Python
PyMongo 查询数据的实现
Jun 28 Python
详解解Django 多对多表关系的三种创建方式
Aug 23 Python
分享Python异步爬取知乎热榜
Apr 12 Python
python GUI库图形界面开发之PyQt5信号与槽多窗口数据传递详细使用方法与实例
Mar 08 #Python
python GUI库图形界面开发之PyQt5多线程中信号与槽的详细使用方法与实例
Mar 08 #Python
python GUI库图形界面开发之PyQt5结合Qt Designer创建信号与槽的详细方法与实例
Mar 08 #Python
python输出第n个默尼森数的实现示例
Mar 08 #Python
Tensorflow之梯度裁剪的实现示例
Mar 08 #Python
Django自定义全局403、404、500错误页面的示例代码
Mar 08 #Python
Django 自定义404 500等错误页面的实现
Mar 08 #Python
You might like
php ss7.5的数据调用 (笔记)
2010/03/08 PHP
采用thinkphp自带方法生成静态html文件详解
2014/06/13 PHP
PHP与Ajax相结合实现登录验证小Demo
2016/03/16 PHP
php 生成Tab键或逗号分隔的CSV
2016/09/24 PHP
PHPUnit + Laravel单元测试常用技能
2019/11/06 PHP
php生成短网址/短链接原理和用法实例分析
2020/05/29 PHP
Ajax+Json 级联菜单实现代码
2009/10/27 Javascript
一个简单的全屏图片上下打开显示网页效果示例
2014/07/08 Javascript
JavaScript中的toLocaleDateString()方法使用简介
2015/06/12 Javascript
js+div实现文字滚动和图片切换效果代码
2015/08/27 Javascript
JavaScript生成二维码图片小结
2015/12/27 Javascript
学习javascript面向对象 实例讲解面向对象选项卡
2016/01/04 Javascript
JS Array创建及concat()split()slice()的使用方法
2016/06/03 Javascript
vue路由传参页面刷新参数丢失问题解决方案
2019/10/08 Javascript
JS实现audio音频剪裁剪切复制播放与上传(步骤详解)
2020/07/28 Javascript
windows下wxPython开发环境安装与配置方法
2014/06/28 Python
Python编程深度学习计算库之numpy
2018/12/28 Python
python如何实现数据的线性拟合
2019/07/19 Python
python+openCV调用摄像头拍摄和处理图片的实现
2019/08/06 Python
深入了解Python在HDA中的应用
2019/09/05 Python
python3实现在二叉树中找出和为某一值的所有路径(推荐)
2019/12/26 Python
Anaconda+Pycharm环境下的PyTorch配置方法
2020/03/13 Python
Django限制API访问频率常用方法解析
2020/10/12 Python
俄罗斯的精英皮具:Wittchen
2018/01/29 全球购物
Haglöfs瑞典官方网站:haglofs火柴棍,欧洲顶级户外品牌
2018/10/18 全球购物
迪士尼英国官方商店:shopDisney UK
2019/09/21 全球购物
Python中如何定义一个函数
2016/09/06 面试题
物流管理专业毕业生自荐信
2014/03/04 职场文书
降消项目实施方案
2014/03/30 职场文书
小学生国旗下演讲稿
2014/04/25 职场文书
教师节班会开场白
2015/06/01 职场文书
2016高考寄语集锦
2015/12/04 职场文书
何时使用Map来代替普通的JS对象
2021/04/29 Javascript
IDEA使用SpringAssistant插件创建SpringCloud项目
2021/06/23 Java/Android
浅谈redis的过期时间设置和过期删除机制
2022/03/18 MySQL
基于Python实现射击小游戏的制作
2022/04/06 Python