PyQt——键盘事件和鼠标事件

PyQt为事件处理提供了两种机制:高级的信号和槽机制,以及低级的事件处理程序。
PyQt为拦截和处理事件提供了5种不同的方式,这里只介绍最常用的头两种方式。
第一种是重新实现特定事件,如键盘和鼠标事件、重绘事件、尺寸大小改变事件等等,的处理程序。可参见代码示例。

第二种重新实现event()事件处理程序 。因为在任何特殊的事件处理程序被调用前,都会调用event()。重新实现这个方法,可以允许我们处理那些不能在某一特定事件处理程序(如对Tab键焦点转换行为的重新定义)中处理的事件,或者实现那些不存在明确事件处理程序的事件,比如QEvent.ToolBarChange。当需要重新实现这些处理程序时,可以对所有其它不是自己亲自处理的事件调用它们的基类的实现。

import sys
from PyQt5.QtWidgets import QMainWindow, QWidget, QApplication
from PyQt5.QtCore import Qt


class MainWindow(QMainWindow):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.initUI()

    def initUI(self):
        self.setWindowTitle("鼠标键盘事件示例")
        self.setCentralWidget(QWidget())  # 指定主窗口中心部件
        self.statusBar().showMessage("ready")  # 状态栏显示信息
        self.resize(300, 185)

    # 重新实现各事件处理程序
    def keyPressEvent(self, event):
        key = event.key()
        if Qt.Key_A <= key <= Qt.Key_Z:
            if event.modifiers() & Qt.ShiftModifier:  # Shift 键被按下
                self.statusBar().showMessage('"Shift+%s" pressed' % chr(key), 500)
            elif event.modifiers() & Qt.ControlModifier:  # Ctrl 键被按下
                self.statusBar().showMessage('"Control+%s" pressed' % chr(key), 500)
            elif event.modifiers() & Qt.AltModifier:  # Alt 键被按下
                self.statusBar().showMessage('"Alt+%s" pressed' % chr(key), 500)
            else:
                self.statusBar().showMessage('"%s" pressed' % chr(key), 500)

        elif key == Qt.Key_Home:
            self.statusBar().showMessage('"Home" pressed', 500)
        elif key == Qt.Key_End:
            self.statusBar().showMessage('"End" pressed', 500)
        elif key == Qt.Key_PageUp:
            self.statusBar().showMessage('"PageUp" pressed', 500)
        elif key == Qt.Key_PageDown:
            self.statusBar().showMessage('"PageDown" pressed', 500)
        else:  # 其它未设定的情况
            QWidget.keyPressEvent(self, event)  # 留给基类处理
        '''
        其它常用按键:
        Qt.Key_Escape,Qt.Key_Tab,Qt.Key_Backspace,Qt.Key_Return,Qt.Key_Enter,
        Qt.Key_Insert,Qt.Key_Delete,Qt.Key_Pause,Qt.Key_Print,Qt.Key_F1...Qt.Key_F12,
        Qt.Key_Space,Qt.Key_0...Qt.Key_9,Qt.Key_Colon,Qt.Key_Semicolon,Qt.Key_Equal
        ...
        '''

    def mousePressEvent(self, event):  # 鼠标按下事件
        pos = event.pos()  # 返回鼠标所在点QPoint
        self.statusBar().showMessage('Mouse is pressed at (%d,%d) of widget ' % (pos.x(), pos.y()), 500)
        globalPos = self.mapToGlobal(pos)
        print('Mouse is pressed at (%d,%d) of screen ' % (globalPos.x(), globalPos.y()))

    def mouseReleaseEvent(self, event):  # 鼠标释放事件
        pos = event.pos()  # 返回鼠标所在点QPoint
        self.statusBar().showMessage('Mouse is released at (%d,%d) of widget ' % (pos.x(), pos.y()), 500)
        if event.button() == Qt.LeftButton:
            print("左键")
        elif event.button() == Qt.MidButton:
            print("中键")
        elif event.button() == Qt.RightButton:
            print("右键")

    def mouseDoubleClickEvent(self, event):  # 鼠标双击事件
        pos = event.pos()  # 返回鼠标所在点QPoint
        self.statusBar().showMessage('Mouse is double-clicked at (%d,%d) of widget ' % (pos.x(), pos.y()), 500)

    def mouseMoveEvent(self, event):  # 鼠标移动事件
        pos = event.pos()  # 返回鼠标所在点QPoint
        self.statusBar().showMessage('Mouse is moving at (%d,%d) of widget ' % (pos.x(), pos.y()), 500)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    mw = MainWindow()
    mw.show()
    sys.exit(app.exec_())
 键盘事件被频繁处理。例如,按下F1,显示帮助信息;在文本编辑框中,按下回车键,输入焦点自动跳到另一控件。下面详细介绍键盘事件。
1.设置输入焦点
在某一时刻,只有一个控件(或根本没有)可以获得输入焦点。指定输入焦点可使用QWidget的下列方法:

setFocus([reason]) - 如果控件在活动窗口中,调用此方法后,该控件成为输入焦点。reason参数可为QtCore.Qt类中的以下枚举变量:
    MouseFocusReason(0):使用鼠标获得焦点;
    TabFocusReason(1):按下了键;
    BacktabFocusReason(2):按下了+组合键;
    ActiveWindowFocusReason(3):窗口变为活动和非活动;
    PopupFocusReason(4):打开或关闭弹出窗口;
    ShortcutFocusReason(5):按下快捷键;
    MenuBarFocusReason(6):通过菜单操作;
    OtherFocusReaaon(7):其他方式。
clearFocus() - 去除输入焦点;
hasFocus() - 如果控件是输入焦点,返回True;否则,返回False;
focusWidget() - 返回最后调用setFocus()方法的控件对象;
setFocusProxy() - 指定获得输入焦点的控件对象;
focusProxy() - 返回获得非当前控件的输入焦点的控件对象;
focusNextChild() - 找到下一个可获得输入焦点的控件对象,并设置为输入焦点。相当于按了键。如果有此控件,返回True;否则,返回False;
focusPreviousChild() - 找到上一个可获得输入焦点的控件对象,并设置为输入焦点。相当于按了+键。如果有此控件,返回True;否则,返回False;
focusNextPrevChild() -  如果isnext参数为True,功能相当于focusNextChild();如果isnext参数为False,功能相当于focusPreviousChild();
setTabOrder(,) - 静态函数。用于指定按下键时,输入焦点的移动顺序。component2是当输入焦点在component1是按下键后的输入焦点所在的控件。如果有多个控件,则需要调用多次。例如,指定输入焦点在按下键的变化顺序为widget1->widget2->widget3->widget4,相应的代码为:
QtWidgets.QWidget.setTabOrder(widget1,widget2)
QtWidgets.QWidget.setTabOrder(widget2,widget3)
QtWidgets.QWidget.setTabOrder(widget3,widget4)
setFocusPolicy () - 指定控件如何获得输入焦点。Method可以QtCore.Qt类以一的枚举对象:
    nofocus(0):不能获得输入焦点;
    TabFocus(1):用键获得;
    ClickFocus(2):用点击鼠标获得;
    strongFocus(11):用键和点击鼠标获得;
    wheelFocus(15):用键、点击鼠标和滚轮获得;
focusPolicy():返回当前获得输入焦点的方式;
grabKeyboard():限定键盘输入。在调用releaseKeyboard()之前,其他控件无法获得输入焦点;
releaseKeyboard():释放之前所作的键盘输入限定。 

QApplication类的静态方法focusWidget()返回拥有键盘输入焦点的应用程序顶级窗口。如果还有,返回None.
QWidget类的下列方法可用来处理焦点事件:

focusInEvent(self, event) - 获得焦点时被调用;
focusOutEvent(self,even) - 失去焦点时被调用;

event参数为QFocusEvent类的实例,有以下方法:

gotFocus() - 如果event的类型为QEvent.FocusIn,返回True,否则,返回False;
lostFocus() - 如果event的类型为QEvent.FocusOut,返回True,否则,返回False;
reason() - 返回设置输入焦点的原因。
判断鼠标点击事件——左键按下、中键按下、右键按下、左右键同时按下
from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia
 
 
class myLabel (QtWidgets.QLabel):  # 自定义的QLabel类
 
    def __init__(self, parent=None):
        super (myLabel, self).__init__ (parent)
 
    def mousePressEvent(self, e):  ##重载一下鼠标点击事件
        # 左键按下
        if e.buttons () == QtCore.Qt.LeftButton:
            self.setText ("左")
        # 右键按下
        elif e.buttons () == QtCore.Qt.RightButton:
            self.setText ("右")
        # 中键按下
        elif e.buttons () == QtCore.Qt.MidButton:
            self.setText ("中")
        # 左右键同时按下
        elif e.buttons () == QtCore.Qt.LeftButton | QtCore.Qt.RightButton:
            self.setText ("左右")
        # 左中键同时按下
        elif e.buttons () == QtCore.Qt.LeftButton | QtCore.Qt.MidButton:
            self.setText ("左中")
        # 右中键同时按下
        elif e.buttons () == QtCore.Qt.MidButton | QtCore.Qt.RightButton:
            self.setText ("右中")
        # 左中右键同时按下
        elif e.buttons () == QtCore.Qt.LeftButton | QtCore.Qt.MidButton | QtCore.Qt.RightButton:
            self.setText ("左中右")
 
 
class MyWindow (QtWidgets.QWidget):
    def __init__(self):
        super (MyWindow, self).__init__ ()
        self.label = myLabel ("点我")
        self.gridLayout = QtWidgets.QGridLayout (self)
        self.gridLayout.addWidget (self.label, 0, 0, 1, 1)
 
 
if __name__ == "__main__":
    import sys
 
    app = QtWidgets.QApplication (sys.argv)
    myshow = MyWindow ()
    myshow.show ()
    sys.exit (app.exec_ ())
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极地星光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值