pyqt在弹出窗口中响应键盘事件

查看:149
本文介绍了pyqt在弹出窗口中响应键盘事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

在主界面中点击控件弹出新窗口用于输入必要的数据,但弹出窗口中不响应键盘事件,现求助解决办法
ps:代码为python3.3.2、pyqt5.6,回答的话用pyqt4也无妨,只是想知道解决的方法,具体代码我可以自己研究,先谢过咯
详细解释:
1、下图主界面中点击悬赏妖怪下面的line_edit控件(注:lineEdit控件设为只读)会弹出新窗口用于输入

2、在下图中的弹出界面中直接输入字母,会下在方的line_eidt中显示输入的字母组合(注:lineEdit控件设置为只读,显示字母组合在KeyPressEvent方法中用setText方法实现),会在上方的table_view中显示相应字母组合为首字母的条目供选择,双击选择之后将选择的条目中的数据填入主界面中的LineEdit中

3、现在遇到的问题:重写的弹出窗口的KeyPressEvent方法,但是在实际运行中弹出窗口并不响应键盘事件
以下是代码

主窗口UI代码

# -*- coding: utf-8 -*-

class UiMainBoard(object):
    def setup_ui(self, main_board):
        # 更改主控件名称和大小
        main_board.setObjectName("main_board")
        main_board.resize(640, 480)

        # 主布局所在控件horizontalLayoutWidget
        self.horizontal_layout_widget = QtWidgets.QWidget(main_board)
        self.horizontal_layout_widget.setGeometry(QtCore.QRect(10, 10, 620, 460))
        self.horizontal_layout_widget.setObjectName("horizontal_layout_widget")

        # 主布局水平布局horizontalLayout
        self.horizontal_layout = QtWidgets.QHBoxLayout(self.horizontal_layout_widget)
        self.horizontal_layout.setContentsMargins(0, 0, 0, 0)
        self.horizontal_layout.setObjectName("horizontal_layout")

        # 1.左侧垂直布局vertical_layout(1.x为布局中的元素)
        self.vertical_layout = QtWidgets.QVBoxLayout()
        self.vertical_layout.setObjectName("vertical_layout")

        # 1.1标签1——悬赏妖怪
        self.label_1 = QtWidgets.QLabel(self.horizontal_layout_widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(16)
        self.label_1.setFont(font)
        self.label_1.setObjectName("label_1")
        self.vertical_layout.addWidget(self.label_1)

        # checkBox与editLine的组合四组

        # 1.2————第一组
        self.horizontal_layout_1 = QtWidgets.QHBoxLayout()
        self.horizontal_layout_1.setObjectName("horizontal_layout_1")

        self.check_box_1 = QtWidgets.QCheckBox(self.horizontal_layout_widget)
        self.check_box_1.setText("")
        self.check_box_1.setObjectName("check_box_1")
        self.horizontal_layout_1.addWidget(self.check_box_1)

        self.line_edit_1 = QtWidgets.QLineEdit(self.horizontal_layout_widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(16)
        self.line_edit_1.setFont(font)
        self.line_edit_1.setObjectName("line_edit_1")
        self.line_edit_1.setReadOnly(True)
        self.horizontal_layout_1.addWidget(self.line_edit_1)

        self.vertical_layout.addLayout(self.horizontal_layout_1)

        # 1.3————第二组
        self.horizontal_layout_2 = QtWidgets.QHBoxLayout()
        self.horizontal_layout_2.setObjectName("horizontal_layout_2")

        self.check_box_2 = QtWidgets.QCheckBox(self.horizontal_layout_widget)
        self.check_box_2.setText("")
        self.check_box_2.setObjectName("check_box_2")
        self.horizontal_layout_2.addWidget(self.check_box_2)

        self.line_edit_2 = QtWidgets.QLineEdit(self.horizontal_layout_widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(16)
        self.line_edit_2.setFont(font)
        self.line_edit_2.setObjectName("line_edit_2")
        self.line_edit_2.setReadOnly(True)
        self.horizontal_layout_2.addWidget(self.line_edit_2)

        self.vertical_layout.addLayout(self.horizontal_layout_2)

        # 1.4————第三组
        self.horizontal_layout_3 = QtWidgets.QHBoxLayout()
        self.horizontal_layout_3.setObjectName("horizontal_layout_3")

        self.check_box_3 = QtWidgets.QCheckBox(self.horizontal_layout_widget)
        self.check_box_3.setText("")
        self.check_box_3.setObjectName("check_box_3")
        self.horizontal_layout_3.addWidget(self.check_box_3)

        self.line_edit_3 = QtWidgets.QLineEdit(self.horizontal_layout_widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(16)
        self.line_edit_3.setFont(font)
        self.line_edit_3.setObjectName("line_edit_3")
        self.line_edit_3.setReadOnly(True)
        self.horizontal_layout_3.addWidget(self.line_edit_3)

        self.vertical_layout.addLayout(self.horizontal_layout_3)

        # 1.5————第四组
        self.horizontal_layout_4 = QtWidgets.QHBoxLayout()
        self.horizontal_layout_4.setObjectName("horizontal_layout_4")

        self.check_box_4 = QtWidgets.QCheckBox(self.horizontal_layout_widget)
        self.check_box_4.setText("")
        self.check_box_4.setObjectName("checkBox_8")
        self.horizontal_layout_4.addWidget(self.check_box_4)

        self.line_edit_4 = QtWidgets.QLineEdit(self.horizontal_layout_widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(16)
        self.line_edit_4.setFont(font)
        self.line_edit_4.setObjectName("line_edit_4")
        self.line_edit_4.setReadOnly(True)
        self.horizontal_layout_4.addWidget(self.line_edit_4)

        self.vertical_layout.addLayout(self.horizontal_layout_4)

        # 1.6 弹簧
        self.vertical_layout.addStretch(1)

        # 1.7 标签2——"搜索范围"
        self.label_2 = QtWidgets.QLabel(self.horizontal_layout_widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(16)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.vertical_layout.addWidget(self.label_2)

        # 1.8 网格布局
        self.grid_layout = QtWidgets.QGridLayout()
        self.grid_layout.setObjectName("grid_layout")


        self.check_box_5 = QtWidgets.QCheckBox(self.horizontal_layout_widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(16)
        self.check_box_5.setFont(font)
        self.check_box_5.setObjectName("check_box_5")
        self.grid_layout.addWidget(self.check_box_5, 0, 0, 1, 1)

        self.check_box_6 = QtWidgets.QCheckBox(self.horizontal_layout_widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(16)
        self.check_box_6.setFont(font)
        self.check_box_6.setObjectName("check_box_6")
        self.grid_layout.addWidget(self.check_box_6, 0, 1, 1, 1)

        self.check_box_7 = QtWidgets.QCheckBox(self.horizontal_layout_widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(16)
        self.check_box_7.setFont(font)
        self.check_box_7.setObjectName("check_box_7")
        self.grid_layout.addWidget(self.check_box_7, 1, 0, 1, 1)

        self.check_box_8 = QtWidgets.QCheckBox(self.horizontal_layout_widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(16)
        self.check_box_8.setFont(font)
        self.check_box_8.setObjectName("check_box_8")
        self.grid_layout.addWidget(self.check_box_8, 1, 1, 1, 1)

        self.vertical_layout.addLayout(self.grid_layout)

        # 1.9 弹簧
        self.vertical_layout.addStretch(1)

        # 1.10 标签3——搜索条件
        self.label_3 = QtWidgets.QLabel(self.horizontal_layout_widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(16)
        self.label_3.setFont(font)
        self.label_3.setObjectName("label_3")
        self.vertical_layout.addWidget(self.label_3)

        # 1.11 check_box_9
        self.check_box_9 = QtWidgets.QCheckBox(self.horizontal_layout_widget)
        font = QtGui.QFont()
        font.setFamily("华文楷体")
        font.setPointSize(16)
        self.check_box_9.setFont(font)
        self.check_box_9.setObjectName("check_box_9")
        self.vertical_layout.addWidget(self.check_box_9)

        # 1.12 弹簧*2
        self.vertical_layout.addStretch(1)
        self.vertical_layout.addStretch(1)

        self.horizontal_layout.addLayout(self.vertical_layout)


        self.table_view = QtWidgets.QTableView(self.horizontal_layout_widget)
        self.table_view.setObjectName("table_view")
        self.horizontal_layout.addWidget(self.table_view)
        self.horizontal_layout.setStretch(0, 1)
        self.horizontal_layout.setStretch(1, 2)

        self.re_translate_ui(main_board)
        QtCore.QMetaObject.connectSlotsByName(main_board)

    def re_translate_ui(self, main_board):
        _translate = QtCore.QCoreApplication.translate
        main_board.setWindowTitle(_translate("main_board", "妖怪出处查询"))
        self.label_1.setText(_translate("main_board", "悬赏妖怪:"))
        self.label_2.setText(_translate("main_board", "搜索范围:"))
        self.check_box_5.setText(_translate("main_board", "探索"))
        self.check_box_6.setText(_translate("main_board", "秘闻"))
        self.check_box_7.setText(_translate("main_board", "御魂"))
        self.check_box_8.setText(_translate("main_board", "妖气封印"))
        self.label_3.setText(_translate("main_board", "搜索条件:"))
        self.check_box_9.setText(_translate("main_board", "包含多个")

弹出窗口UI,逻辑和主程序代码

# -*- coding: utf-8 -*-

from PyQt5 import QtWidgets, QtCore
from Onmyoji_search_ui import UiMainBoard


class MonsterNameShow(QtWidgets.QMainWindow):

    def setup_ui(self):
        self.main_widget = QtWidgets.QWidget()
        self.setCentralWidget(self.main_widget)

        self.lay_out = QtWidgets.QVBoxLayout(self.main_widget)

        self.table_view = QtWidgets.QTableView()
        self.lay_out.addWidget(self.table_view)

        self.line_edit = QtWidgets.QLineEdit()
        self.line_edit.setReadOnly(True)
        self.lay_out.addWidget(self.line_edit)

    def keyPressEvent(self, event):
        # 测试弹出窗口是否响应键盘事件
        print(event.key())


class OnmyojiSearchShow(QtWidgets.QWidget, UiMainBoard):
    keyPressed = QtCore.pyqtSignal()

    def __init__(self):
        super(OnmyojiSearchShow, self).__init__()

        self.setup_ui(self)
        self.check_box_1.setCheckState(2)
        self.check_box_2.setCheckState(2)
        self.check_box_3.setCheckState(2)
        self.check_box_4.setCheckState(2)
        self.check_box_5.setCheckState(2)
        self.check_box_6.setCheckState(2)
        self.check_box_7.setCheckState(2)
        self.check_box_8.setCheckState(2)
        self.check_box_9.setCheckState(2)
        # 当复选框状态改变时重新运行search方法
        self.check_box_1.stateChanged.connect(self.search)
        self.check_box_2.stateChanged.connect(self.search)
        self.check_box_3.stateChanged.connect(self.search)
        self.check_box_4.stateChanged.connect(self.search)
        self.check_box_5.stateChanged.connect(self.search)
        self.check_box_6.stateChanged.connect(self.search)
        self.check_box_7.stateChanged.connect(self.search)
        self.check_box_8.stateChanged.connect(self.search)
        self.check_box_9.stateChanged.connect(self.search)
        # 双击LineEdit控件弹出窗口
        self.line_edit_1.selectionChanged.connect(lambda: self.monster_select(1))
        self.line_edit_2.selectionChanged.connect(lambda: self.monster_select(2))
        self.line_edit_3.selectionChanged.connect(lambda: self.monster_select(3))
        self.line_edit_4.selectionChanged.connect(lambda: self.monster_select(4))

    def search(self):
        pass

    def monster_select(self, num):
        self.monster_name = MonsterNameShow(self)
        self.monster_name.setup_ui()
        self.monster_name.show()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    my_show = OnmyojiSearchShow()
    my_show.show()
    sys.exit(app.exec_())

`

解决方案

MonsterNameShow窗口弹出之后,焦点默认是在QTableView的,Qt手册上看,QTableView没有keyPressEvent方法。

如果在MonsterNameShow的setup_ui()的末尾,加一句self.line_edit.setFocus(),把焦点设到QLineEdit上,就可以捕获键盘事件了。

补充
如果MonsterNameShow弹出之后,鼠标去点了一下QTableView控件,那焦点又回到QTableView上去了,这时候键盘事件又捕获不到了。
由于实际使用APP的用户的操作是不可控的,用下面的代码加点保险,禁止QTableView控件获得焦点,这样就OK了

self.table_view.setFocusPolicy(QtCore.Qt.NoFocus)
self.line_edit.setFocus()


--- 6/21更新 ---
由于QLineEdit控件是只读的setReadOnly(True)
只是重载class MonsterNameShow(QtWidgets.QMainWindow)的keyPressEvent,退格键捕获不到。
提供一个方法,重载QLineEditkeyPressEvent后,可以捕获到比较全面的key事件。

class LineEdit(QtWidgets.QLineEdit):
    ''' 派生QLineEdit类 '''
    def __init__(self, *args, **kwargs):
        super(LineEdit, self).__init__(*args, **kwargs)

    def keyPressEvent(self, event):
        print(event.key())
        
self.line_edit = QtWidgets.QLineEdit()  # 原来创建line_edit对象的代码,删掉
self.line_edit = LineEdit()             # 替换成这句

这篇关于pyqt在弹出窗口中响应键盘事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆