【问题标题】:Data Entry to Table with Entry key issue使用输入键问题将数据输入到表中
【发布时间】:2021-01-10 10:59:32
【问题描述】:

我已经使用 PyQt5 QTableWidget、QLineEdit、QComboBox 创建了学生数据输入对话框。

这是 PyQt5 代码

import sys
from PyQt5.QtWidgets import (QDialog,
                               QApplication,
                               QGridLayout,
                               QPushButton,
                               QLabel,
                               QLineEdit,
                               QComboBox,
                               QTableWidget,
                               QTableWidgetItem,
                               QAbstractItemView)
from PyQt5.QtCore import Qt

class MyWindow(QDialog):
    def __init__(self):
        super().__init__()

        self.setWindowTitle('Student Data Entry')

        grdLayout = QGridLayout()           

        self.lblStudentId = QLabel('Student Id')
        self.cboStudentId = QComboBox(self)
        self.cboStudentId.addItems(['1000','6001','5000','5002','9000','1004'])
        self.cboStudentId.setCurrentIndex(1)

        self.lblStudentName = QLabel('Student name',self)
        self.ledStudentName = QLineEdit(self)
        
        self.lblAge = QLabel('Age',self)
        self.ledAge = QLineEdit(self)
        self.ledAge.setAlignment(Qt.AlignCenter) 
        self.ledAge.setPlaceholderText('0')

        self.lblAdd = QLabel('Add',self)
        self.btnAdd = QPushButton('Add',self)
        self.btnAdd.clicked.connect(self.addFeeRow)        

        # student data table
        self.tblStudent = QTableWidget(self)
        self.tblStudent.setColumnCount(3)
        self.tblStudent.setShowGrid(True)
        self.tblStudent.setHorizontalHeaderLabels(('Student Id', 'Student name','Age'))
        self.tblStudent.verticalHeader().hide()
        self.tblStudent.setEditTriggers(QTableWidget.NoEditTriggers)
        self.tblStudent.setSelectionBehavior(QAbstractItemView.SelectRows) 
        self.tblStudent.setColumnWidth(0, 50)
        self.tblStudent.setColumnWidth(1, 150)
        self.tblStudent.setColumnWidth(2, 25)         

        # Add Label, LineEdit and ComboBox
        grdLayout.addWidget(self.lblStudentId,0,0)
        grdLayout.addWidget(self.lblStudentName,0,1,1,2)
        grdLayout.addWidget(self.lblAge,0,3)
        grdLayout.addWidget(self.lblAdd,0,4)

        grdLayout.addWidget(self.cboStudentId,1,0)
        grdLayout.addWidget(self.ledStudentName,1,1,1,2)
        grdLayout.addWidget(self.ledAge,1,3)
        grdLayout.addWidget(self.btnAdd,1,4)
        
        # Add table
        grdLayout.addWidget(self.tblStudent,2,0,1,4)

        grdLayout.setColumnStretch(0,1)
        grdLayout.setColumnStretch(1,1)
        grdLayout.setColumnStretch(2,1)    

        self.setLayout(grdLayout)
        
    def addFeeRow(self):
        rowCount = self.tblStudent.rowCount()
        self.tblStudent.insertRow(rowCount)
        # insert into table
        self.tblStudent.setItem(rowCount,0, QTableWidgetItem(self.cboStudentId.currentText()))
        self.tblStudent.setItem(rowCount,1, QTableWidgetItem(self.ledStudentName.text()))
        self.tblStudent.setItem(rowCount,2, QTableWidgetItem(self.ledAge.text()))
       
if __name__ == '__main__':
    app = QApplication()
    window = MyWindow()
    window.show()

我的要求是,

  1. 当用户点击Add QPushButton 或Age QLineEdit 时按Enter 键时,应将数据(学生ID、学生姓名和学生年龄)输入到表中。当用户在 Age QLineEdit 或 Add QPushButton 中按 Enter 键时应将数据输入到表格中。

  2. 此外,当用户在 Student Id QComboBox 中按 Enter 键 时,焦点应移至 下一个小部件(学生姓名)。当用户在 Student Name QLineEdit 中按下 Enter 键 时,焦点应移至 下一个小部件(学生年龄)

在当前场景中,当用户在学生 ID、学生姓名等任何小部件中按 Enter 键时,数据正在输入到表中,这是我不想要的。 请提供限制这种行为的解决方案。

【问题讨论】:

    标签: python python-3.x pyqt pyqt5 pyside2


    【解决方案1】:

    关于从任何地方触发返回键的问题是,当使用 QDialog 和至少一个设置了autoDefault() 属性的按钮时,只要按下返回键就会触发该按钮的clicked 信号。

    为了禁用它,需要以下内容:

            self.btnAdd.setAutoDefault(False)
    

    由于您还想使用该键控制焦点,因此您可以改为实现keyPressEvent,确保在这些情况下不会对其进行处理(在这种情况下,理论上不需要上面的setAutoDefault不再):

        def keyPressEvent(self, event):
            if event.key() in (Qt.Key_Return, Qt.Key_Enter):
                current = QApplication.focusWidget()
                if current == self.cboStudentId:
                    self.ledStudentName.setFocus()
                    return
                elif current == self.ledStudentName:
                    self.ledAge.setFocus()
                    return
                elif current == self.ledAge:
                    self.addFeeRow()
                    self.cboStudentId.setFocus()
                    return
            super().keyPressEvent(event)
    

    最后,如果您还想在用户在组合框的弹出窗口上按下回车键时更改焦点,则必须使用事件过滤器:

    class MyWindow(QDialog):
        def __init__(self):
            # ...
            self.cboStudentId.view().installEventFilter(self)
    
        def eventFilter(self, source, event):
            if (event.type() == QEvent.KeyPress and 
                event.key() in (Qt.Key_Return, Qt.Key_Enter)):
                    self.ledStudentName.setFocus()
            return super().eventFilter(source, event)
    

    【讨论】:

    • 您的解决方案运行良好。多谢。我是否需要使用 self.btnAdd.setAutoDefault(True) 才能使用带有按钮的 Enter 键。如果 self.btnAdd.setAutoDefault(False),Enter 键不能与按钮一起使用。只有鼠标点击有效。 autoDefault() 的默认值是多少。是真的还是假的?
    • @RaviKannan 阅读文档(链接在帖子中),您显然可以通过调用self.btnAdd.autoDefault() 来了解before 设置它的值。也就是说,我已经在问题中写道:“在这种情况下,理论上不再需要上面的setAutoDefault”。
    • 我明白了。感谢您的及时帮助和支持
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 2015-04-15
    相关资源
    最近更新 更多