python3+PyQt5重新实现QT事件处理程序

yipeiwu_com6年前Python基础

本文是对《Python Qt GUI快速编程》的第10章的例子events用Python3+PyQt5进行改写,涉及到重新实现QWidget的事件处理程序。本例子涉及到上下文菜单,鼠标事件,键盘事件,可作为重新实现事件处理程序的参考。

注:在创建上下文菜单最简单的方式使用Qwidget.addAction()把动作添加到窗口部件中,再把窗口部件的上下文菜单策略设置为Qt.ActionsContextMenu即可,但是如果像本例子一样要根据不同的状态来提供不同的选项,则要重新实现上下文菜单事件处理程序。

#!/usr/bin/env python3
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)
    self.justDoubleClicked = False
    self.key = ""
    self.text = ""
    self.message = ""
    self.resize(400, 300)
    self.move(100, 100)
    self.setWindowTitle("Events")
    QTimer.singleShot(0, self.giveHelp) # Avoids first resize msg


  def giveHelp(self):
    self.text = "Click to toggle mouse tracking"
    self.update()


  def closeEvent(self, event):
    print("Closed")


  def contextMenuEvent(self, event):
    menu = QMenu(self)
    oneAction = menu.addAction("&One")
    twoAction = menu.addAction("&Two")
    oneAction.triggered.connect(self.one)
    twoAction.triggered.connect(self.two)
    if not self.message:
      menu.addSeparator()
      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\nYou pressed: {0}".format(self.key)
    painter = QPainter(self)
    painter.setRenderHint(QPainter.TextAntialiasing)
    painter.drawText(self.rect(), Qt.AlignCenter, text)
    if self.message:
      painter.drawText(self.rect(), Qt.AlignBottom|Qt.AlignHCenter,
               self.message)
      QTimer.singleShot(5000, self.clearMessage)
      QTimer.singleShot(5000, self.update)

  def clearMessage(self):
    self.message=""

  def resizeEvent(self, event):
    self.text = "Resized to 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 = "Mouse tracking is on.\n"+\
            "Try moving the mouse!\n"+\
            "Single click to switch it off"
      else:
        self.text = "Mouse tracking is off.\n"+\
                      "Single click to switch it on"
      self.update()


  def mouseMoveEvent(self, event):
    if not self.justDoubleClicked:
      globalPos = self.mapToGlobal(event.pos())
      self.text = "The mouse is at\nQPoint({0}, {1}) "+\
          "in widget coords, and\n"+\
          "QPoint({2}, {3}) in screen coords".format(
          event.pos().x(), event.pos().y(), globalPos.x(),
          globalPos.y())
      self.update()


  def mouseDoubleClickEvent(self, event):
    self.justDoubleClicked = True
    self.text = "Double-clicked."
    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()
    if self.key:
      self.key = self.key
      self.update()
    else:
      QWidget.keyPressEvent(self, event)


  def event(self, event):
    if (event.type() == QEvent.KeyPress and
      event.key() == Qt.Key_Tab):
      self.key = "Tab captured in event()"
      self.update()
      return True
    return QWidget.event(self, event)

if __name__ == "__main__":
  app = QApplication(sys.argv)
  form = Widget()
  form.show()
  app.exec_()

运行结果:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持【听图阁-专注于Python设计】。

相关文章

Python中的文件和目录操作实现代码

本文将详细解释这些函数的使用方法。首先,我们介绍Python语言中类似于Windows系统的dir命令的列出文件功能,然后描述如何测试一个文件名对应的是一个标准文件、目录还是链接,以及提...

python路径的写法及目录的获取方式

获取文件目录的方法 : import os # '***获取当前目录***' os.getcwd() # '***获取上级目录***' os.path.abspath(os.path...

Python基类函数的重载与调用实例分析

本文实例讲述了Python基类函数的重载与调用方法。分享给大家供大家参考。具体分析如下: 刚接触Python语言的时间不长,对于这个语言的很多特性并不是很了解,有很多用法都是还不知道。今...

Python入门Anaconda和Pycharm的安装和配置详解

Python入门Anaconda和Pycharm的安装和配置详解

子曰:“工欲善其事,必先利其器。”学习Python就需要有编译Python程序的软件,一般情况下,我们选择在Python官网下载对应版本的Python然后用记事本编写,再在终端进行编译运...

Python 循环语句之 while,for语句详解

循环语句(有两种): while 语句 for   语句 while 语句: 问题:输入一个整数n,让程序输出n行的: hello 1 hello 2 ....