美文网首页
PyQt5编程(18):键盘事件

PyQt5编程(18):键盘事件

作者: 用电热毯烤猪 | 来源:发表于2018-01-01 21:40 被阅读0次
     键盘事件被频繁处理。例如,按下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() - 返回设置输入焦点的原因。
    

    下面的代码为:
    创建一个带有按钮和两个单行编辑框的窗口。 对于单行编辑框,我们处理获得和失去输入焦点的事件。通过按下按钮,我们将输入焦点设置为第二个单行编辑框。 另外,通过按键可切换输入焦点。

    -- coding: utf-8 --

    from PyQt5 import QtWidgets

    class MyLineEdit(QtWidgets.QLineEdit):
    def init(self, id, parent=None):
    QtWidgets.QLineEdit.init(self, parent)
    self.id = id
    def focusInEvent(self, e):
    print("输入焦点在", self.id)
    QtWidgets.QLineEdit.focusInEvent(self, e)
    def focusOutEvent(self, e):
    print(self.id,"失去输入焦点")
    QtWidgets.QLineEdit.focusOutEvent(self, e)

    class MyWindow(QtWidgets.QWidget):
    def init(self, parent=None):
    QtWidgets.QWidget.init(self, parent)
    self.resize(300, 100)
    self.button = QtWidgets.QPushButton("设置输入焦点在编辑框 2")
    self.line1 = MyLineEdit(1)
    self.line2 = MyLineEdit(2)
    self.vbox = QtWidgets.QVBoxLayout()
    self.vbox.addWidget(self.button)
    self.vbox.addWidget(self.line1)
    self.vbox.addWidget(self.line2)
    self.setLayout(self.vbox)
    self.button.clicked.connect(self.on_clicked)
    # 指定顺序
    QtWidgets.QWidget.setTabOrder(self.line1, self.line2)
    QtWidgets.QWidget.setTabOrder(self.line2, self.button)
    def on_clicked(self):
    self.line2.setFocus()

    if name == "main":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())

    2.设置快捷键
    快捷键(也要称热键)一些特别键的组合,用来快速设置输入焦点。按下输入焦点所在按钮的快捷键,按钮将被按下。
    要设置快捷键,需要在相应字母前加上“&”,程序运行后,在相应字母下加上下划线以提示用户。 按下+带下划线的字母,对应的控件获得输入焦点。对于编辑框这类没有文本的控件,在设置快捷键时,要先创建一个QLabel对象,并通过调用 setBuddy(component)与控件相关联。如果不想创建QLabel对象,可使用QWidget的下列方法:
    
    grabShortcut (Keys [,Context]) - 登记快捷键,返回一个标识符。参数Keys为QKeySequence对象。设置+快捷键的Keys设置方式为:
        QtQui.QKeySequence.mmemonic("&e")
        QtGui.QKeySequence("Alt+e")
        QtGui.QKeySequence(QtCore.Qt.ALT + QtCore.Qt.Key_E)
    
          Context参数可设置为Qt中的枚举变量:WidgetShortcut、WidgetWithChildrenShortcut、WindowsShortcut(默认值 )和ApplicationShortcut。
    
    releaseshortcut (ID) - 删除标识符为ID的组合键;
    setShortcutEnabled(ID[,Flag]) -  Flag为True时,标识符为ID的组合键有效;否则,无效。
    
    按下快捷键时,产生QEvent.Shortcut事件,可在函数event(self,event)中处理。event参数是QShortcutEvent对象,有以下方法:
    
    shortcutId():返回快捷键的标识符。
    isAmbiguous():如果事件同时发送给几个控件,返回True;否则,返回Fasle.
    key():返回代表所按下快捷键的QkeySequence对象。
    

    -- coding: utf-8 --

    from PyQt5 import QtCore, QtGui, QtWidgets

    class MyLineEdit(QtWidgets.QLineEdit):
    def init(self, parent=None):
    QtWidgets.QLineEdit.init(self, parent)
    self.id = None
    def event(self, e):
    if e.type() == QtCore.QEvent.Shortcut:
    if self.id == e.shortcutId():
    self.setFocus(QtCore.Qt.ShortcutFocusReason)
    return True
    return QtWidgets.QLineEdit.event(self, e)

    class MyWindow(QtWidgets.QWidget):
    def init(self, parent=None):
    QtWidgets.QWidget.init(self, parent)
    self.resize(300, 100)
    self.label = QtWidgets.QLabel("(&E)设置输入焦点在编辑框1")
    self.lineEdit1 = QtWidgets.QLineEdit()
    self.label.setBuddy(self.lineEdit1)
    self.lineEdit2 = MyLineEdit()
    self.lineEdit2.id = self.lineEdit2.grabShortcut(
    QtGui.QKeySequence.mnemonic("&D"))
    self.button = QtWidgets.QPushButton("(&R)删除编辑框1的输入焦点")
    self.vbox = QtWidgets.QVBoxLayout()
    self.vbox.addWidget(self.label)
    self.vbox.addWidget(self.lineEdit1)
    self.vbox.addWidget(self.lineEdit2)
    self.vbox.addWidget(self.button)
    self.setLayout(self.vbox)
    self.button.clicked.connect(self.on_clicked)
    def on_clicked(self):
    self.lineEdit1.clearFocus()

    if name == "main":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.show()
    sys.exit(app.exec_())

    除了上面介绍的方式,还可以通过QtWidgets模块中的QShortcut类来实现:
    

    self.lineEdit2 = QtWidgets.QLineEdit()
    self.shc = QtWidgets.QShortcut(QtGui.QKeySequence.mnemonic("&D"), self)
    self.shc.setContext(QtCore.Qt.WindowShortcut)
    self.shc.activated.connect(self.lineEdit2.setFocus)
    或者使用QtWidgets模块中的QAction类来实现:
    self.lineEdit2 = QtWidgets.QLineEdit()
    self.act = QtWidgets.QAction(self)
    self.act.setShortcut(QtGui.QKeySequence.mnemonic("&е"))
    self.act.triggered.connect(self.lineEdit2.setFocus)
    self.addAction(self.act)

    3.按下并释放键
    按下并释放键时,以下方法将被调用:
    
    keyPressEvent(self,event) - 按下某一键时,该方法被调用直到键被释放为止;
    keyReleaseEvent(self,event) - 释放之前按下的键时被调用。event参数为QKeyEvent对象,包括事件的相关信息,有以下方法可调用。(详见QKeyEvent文档http://doc.qt.io/qt-5/qkeyevent.html)
    key():返回按下键的值;
    text():返回按下键的Unicode字符编码信息,当按键为Shift, Control, Alt等时,则该函数返回的字符为空值;
    modifiers():判断按下了哪些修饰键(Shift,Ctrl , Alt,等等)。返回值为QtCore.Qt 类以下枚举变量的组合:
        NoModifier - 没有修饰键;
        ShiftModifier - 修饰键;
        ControlModifier - 修饰键;
        AltModifier - 修饰键;
        MetaModifier - 修饰键;
        KeypadModifier - 附加键盘上的任何按键;
        GroupSwitchModifier - 按下键(仅限X11系统)。
    isAutoRepeat(): 如果一直按着某键,返回True;否则,返回False;
    match(QKeySequence.StandardKey key): 如果当前的键组合与key相同,返回True;否则,返回False. 比如,是否按下了复制快捷键的代码:
    if e.matches(QtGui.QKeySequence.Copy):
        print("组合键为 +")
    
    处理键盘按键时,要注意以下几点:
    
    控件必须可以设置为输入焦点。有些控件,如QLabel是不能接受输入焦点的。
    捕获键盘事件要使用grabKeyboard( )方法,释放时,调用rekeaseKeyboard().
    可能拦截除和+以外的任何键。要拦截这两个键,只能在event(self,event)中完成。
    如果要让父控件继续收到键盘事件,要调用事件的ignore()方法;否则,调用accept()。
    

    相关文章

      网友评论

          本文标题:PyQt5编程(18):键盘事件

          本文链接:https://www.haomeiwen.com/subject/ofrxnxtx.html