zoukankan      html  css  js  c++  java
  • PyQt5-事件处理机制

    PyQt中提供了两种针对事件处理的机制:一种是信号和槽,另一种则是事件;事件处理在PyQt中是比较底层的,这里的事件常见如下类型:

    键盘事件、鼠标事件、拖放事件、滚轮事件、定时事件、焦点事件、进入和离开事件(光标移入控件或者移出),移动事件(窗口位置变化),

    显示和隐藏事件,窗口事件(窗口是否为当前窗口)、以及常见的Qt事件:Socket事件、剪贴板事件、文字改变事件,布局改变事件;

    PyQt提供了5中事件处理和过滤方法,弱到强,其中前两者常用;

    (1)重写事件具体的函数(例如:mousePressEvent()/keyPressEvent()....)

    (2)重新实现QObject.event()一般用在PyQt没有提供该事件的处理函数的情况下,即添加一个新的事件;

    (3)通过事件过滤器

    对QObject调用installEventFilter,则相当于为QObject安装了一个事件过滤器;对于QObject的全部事件来说,他们会先传递到事件过滤函数eventFilter中;

    在函数中我们可以放弃或者修改某些事件,如果该过滤事件比较多,则会降低性能;

    (4)在QApplication中设置事件过滤器

    这种方式比前者更强大,QApplication的事件过滤器会捕获所有QObject的事件,且第一个获得事件,即在任意一个事件过滤器之前捕获;

    (5)重写QApplication中notify()方法;

      使用notify方法来分发事件;想在任意事件处理器之前捕获事件,则唯一方法就是从写notify方法;

    例如:(1)(2)重写具体事件和event函数;

     1 #事件机制
     2 #信号与槽(QTabWidget略)自定义参数
     3 from PyQt5.QtWidgets import  QComboBox,QTableView,QAbstractItemView,QHeaderView,QTableWidget, QTableWidgetItem, QMessageBox,QListWidget,QListWidgetItem, QStatusBar,  QMenuBar,QMenu,QAction,QLineEdit,QStyle,QFormLayout,   QVBoxLayout,QWidget,QApplication ,QHBoxLayout, QPushButton,QMainWindow,QGridLayout,QLabel
     4 from PyQt5.QtGui import QIcon,QPixmap,QStandardItem,QStandardItemModel,QCursor,QFont,QBrush,QColor,QPainter
     5 from PyQt5.QtCore import QStringListModel,QAbstractListModel,QModelIndex,QSize,Qt,QObject,pyqtSignal,QTimer,QEvent
     6 
     7 import sys
     8 class Win(QWidget):
     9     def __init__(self,parent=None):
    10 
    11         super(Win, self).__init__(parent)
    12         self.message=""
    13         self.btn1=QPushButton("点击1",self)
    14         self.btn1.move(20,40)
    15         self.btn1.clicked.connect(lambda :self.btnFn(1))#点击按钮,执行btnFn方法
    16 
    17         self.btn2 = QPushButton("点击2", self)
    18         self.btn2.move(140,40)
    19         self.btn2.clicked.connect(lambda: self.btnFn(2))  # 点击按钮,执行btnFn方法
    20     def btnFn(self,flag):
    21         if flag==1:
    22             print("点击了第一个按钮")
    23         else:
    24             print("点击了第二个按钮")
    25 
    26 
    27     #上面之前的实例,下面从写按键事件方法
    28     ###第一种方式
    29     def keyPressEvent(self, QKeyEvent):#重写按键事件
    30         if QKeyEvent.key()==Qt.Key_A:#按A建
    31            self.btn1.click()
    32         if  QKeyEvent.key()==Qt.Key_Tab:
    33             print("TABTAB")
    34 
    35     def closeEvent(self, QCloseEvent):#重写关闭窗口事件
    36         print("重写关闭窗口事件closeEvent")
    37 
    38     def contextMenuEvent(self, even):#重写上下文菜单事件
    39         menu=QMenu(self)
    40         oneAction=menu.addAction("One")
    41         oneAction.triggered.connect(self.one)
    42 
    43         menu.addSeparator()#菜单添加分割线
    44         twoAction=menu.addAction("Two")
    45         twoAction.triggered.connect(self.two)
    46 
    47         menu.exec_(even.globalPos())#事件触发在任意位置
    48 
    49     def one(self):
    50         print("one")
    51         self.message="Menu option One"
    52         self.update()
    53     def two(self):
    54         print("two")
    55         self.message="Menu option Two"
    56         self.update()
    57 
    58     def paintEvent(self, event):#重写绘制事件
    59         painter=QPainter(self)
    60         painter.setRenderHint(QPainter.TextAntialiasing)
    61         painter.drawText(self.rect(),Qt.AlignCenter,self.message)
    62         QTimer.singleShot(15000,self.clearMessage)#清空数据
    63         QTimer.singleShot(15000,self.update)#更新当前组件
    64 
    65     def clearMessage(self):
    66         self.message=""
    67 
    68     def resizeEvent(self, event):#更新窗体大小事件
    69         self.message="窗口大小调整为:QSize({0},{1})".format(event.size().width(),event.size().height())
    70         self.update()
    71 
    72     ###第二种方式,一般适用于PyQt没有提供事件处理函数情况,需要自定义事件,例如:
    73         #Tab按键不会传递给keyPressEvent;
    74        #第二种方式则是重写event函数,所有针对窗口的事件都会传递给event函数,event会根据事件的类型,讲事件分配给不同函数处理;
    75 
    76     def event(self,event):
    77         #?????下面捕获不到tab按键的事件,if判断始终未false,不知道为何,待解决;???
    78         if ( event.type() == QEvent.KeyPress and event.key() == Qt.Key_Tab ):
    79             print("Tab")
    80             self.message="在event()中捕获Tab按键触发的事件"
    81             self.update()
    82             return True
    83         return QWidget.event(self,event)
    84 
    85 
    86 if __name__=='__main__':
    87 
    88     app=QApplication(sys.argv)
    89     win = Win()
    90     win.show()
    91     sys.exit(app.exec_())

    例如:(3)事件过滤器;单击按钮获取左键或者右键单击事件;

     1 #事件机制
     2 from PyQt5.QtWidgets import  QDialog,QComboBox,QTableView,QAbstractItemView,QHeaderView,QTableWidget, QTableWidgetItem, QMessageBox,QListWidget,QListWidgetItem, QStatusBar,  QMenuBar,QMenu,QAction,QLineEdit,QStyle,QFormLayout,   QVBoxLayout,QWidget,QApplication ,QHBoxLayout, QPushButton,QMainWindow,QGridLayout,QLabel
     3 from PyQt5.QtGui import QIcon,QPixmap,QStandardItem,QStandardItemModel,QCursor,QFont,QBrush,QColor,QPainter,QMouseEvent,QImage,QTransform
     4 from PyQt5.QtCore import QStringListModel,QAbstractListModel,QModelIndex,QSize,Qt,QObject,pyqtSignal,QTimer,QEvent
     5 
     6 import sys
     7 class Win(QWidget):
     8     def __init__(self,parent=None):
     9         super(Win, self).__init__(parent)
    10         self.resize(400,400)
    11 
    12         self.btn=QPushButton("按钮",self)
    13         self.btn.move(50,50)
    14         self.btn.setMinimumWidth(220)
    15 
    16         self.image=QImage("./image/7.ico")
    17         self.label=QLabel('图片',self)
    18         self.label.setMinimumWidth(600 )
    19         self.label.setMinimumHeight(400)
    20         self.label.move(100,150)
    21         self.label.setPixmap(QPixmap(self.image))
    22 
    23         #对按钮添加事件过滤器
    24         self.btn.installEventFilter(self)
    25 
    26     def  eventFilter(self,obj, event):
    27          if obj==self.btn:
    28              if event.type()==QEvent.MouseButtonPress:
    29                 mouseEvent=QMouseEvent(event)
    30                 if mouseEvent.buttons()==Qt.LeftButton:
    31                    self.btn.setText("按鼠标左键缩小图片")
    32                    transform=QTransform()
    33                    transform.scale(0.5,0.5)#设置缩放多少倍
    34                    self.label.setPixmap(QPixmap.fromImage(self.image.transformed(transform)))#将label中图片设置缩放效果
    35                 if mouseEvent.buttons()==Qt.RightButton:
    36                     self.btn.setText("按鼠标右键放大图片")
    37                     transform = QTransform()
    38                     transform.scale(1.5, 1.5)#设置缩放多少倍
    39                     self.label.setPixmap(QPixmap.fromImage(self.image.transformed(transform)))
    40          return QWidget.eventFilter(self,obj,event)
    41     
    42 if __name__=='__main__':
    43 
    44     app=QApplication(sys.argv)
    45     win = Win()
    46     win.show()
    47     sys.exit(app.exec_())

    关于(4)和(5)略,这里不写例子了;

    补充:

    第四种在QApplication中安装事件监听,只需要修改上面程序即可:

     app=QApplication(sys.argv)
        win = Win()
        #
        app.installEventFilter(win)  #安装事件过滤器,将前面代码中按钮的installEventFilter注释掉即可
        #
        win.show()
        sys.exit(app.exec_())
  • 相关阅读:
    Prommetheus 插件监控 ES
    Linux LVM条带化
    MYSQL wait_timeout以及connect_timeout.这两个有什么区别
    alertmanager配置文件说明(转载)
    腾讯云MongoDB: skip查询内核优化(转载)
    MongoDB主从复制介绍和常见问题说明(转载)
    MongoDB 批量更新、批量新增、批量删除、批量替换 —— bulkWrite操作
    MongoDB Cluster 数据平衡优化
    MongoDB副本集提高读写速率
    Postgresql中时间戳与日期的相互转换(同样适用于GreenPlum)
  • 原文地址:https://www.cnblogs.com/ygzhaof/p/10132824.html
Copyright © 2011-2022 走看看