PyQt QTableWidget 获取编辑字段

2 投票
1 回答
4831 浏览
提问于 2025-04-18 17:35

我刚开始接触PyQt,正在用PyQt4和Python 2.7制作一个图形界面,这个界面可以控制一些微控制器的设置。为了方便显示和管理这些设置,我把它们放进了一个QTableWidget里,列是微控制器,行是设置(所有的微控制器其实都是一样的,只是每个控制器的设置值可能不一样)。

我遇到的问题是,当用户编辑某个单元格时,我想获取这个新输入的值,使用了

value = self.Settings1Table.item(n, s).text()

但是这样只能获取到我之前放进去的值,而不是用户刚刚通过键盘输入的值。我听说过一个方法叫currentText(),但我了解到这个方法需要每个单元格都是一个独立的控件,我不太清楚怎么实现。

整个代码比较长,我觉得没必要全部贴出来,不过如果需要更多代码,我可以提供。谢谢大家的帮助,希望能得到一些建议。

编辑:这是一个遍历表格中每个项目的方法,应该是用来获取当前值的,但现在只返回我通过item.setText(str)设置的值(我需要的是用户通过键盘输入的值)。

def ApplyAll1(self):
    if not self.CheckHealth():
        for s in xrange(NumOfSegs):
            n = 0
            for item in Settings1List:
                value = self.Settings1Table.item(n, s).text()
                print value
    else:
        self.MsgCntrField.setText("CONNECTION ERROR")

self.CheckHealth()只是用来检查错误的。

1 个回答

2

最后更新于 2014年8月19日 0:29

我并不太在乎这个事件,因为我会遍历整个表格。我需要的是通过键盘改变的数据,而不是通过 'QtGui.QTableWidgetItem.setText' 所设置的内容,所以是的。

好的,确实可以只创建键盘事件,但你需要实现 QtGui.QTableWidget.focusInEvent(self, eventQFocusEvent)QtGui.QTableWidget.focusOutEvent(self, eventQFocusEvent)。所以,请看看我的示例代码,希望能帮到你;

import sys
from PyQt4 import QtGui, QtCore

class QCustomTableWidget (QtGui.QTableWidget):
    def __init__ (self, parent = None):
        super(QCustomTableWidget, self).__init__(parent)
        self.focusKeyboardOn = False
        # Setup row & column data
        listsVerticalHeaderItem = ['Device 1', 'Device 2', 'Device 3', 'Device 4', 'Device 5']
        self.setRowCount(len(listsVerticalHeaderItem))
        for index in range(self.rowCount()):
            self.setVerticalHeaderItem(index, QtGui.QTableWidgetItem(listsVerticalHeaderItem[index]))
        listsVerticalHeaderItem = ['Device 1', 'Device 2', 'Device 3', 'Device 4']
        self.setColumnCount(5)
        listsHorizontalHeaderItem = ['Option 1', 'Option 2']
        self.setColumnCount(len(listsHorizontalHeaderItem))
        for index in range(self.columnCount()):
            self.setHorizontalHeaderItem(index, QtGui.QTableWidgetItem(listsHorizontalHeaderItem[index]))

    def dataChanged (self, topLeftQModelIndex, bottomRightQModelIndex):
        row                  = topLeftQModelIndex.row()
        column               = topLeftQModelIndex.column()
        dataQTableWidgetItem = self.item(row, column)
        if (self.currentItem() == dataQTableWidgetItem) and (self.focusKeyboardOn == True):
            self.emit(QtCore.SIGNAL('currentKeyboardDataChanged'), row, column, dataQTableWidgetItem)
        self.emit(QtCore.SIGNAL('dataChanged'), row, column, dataQTableWidgetItem)
        QtGui.QTableWidget.dataChanged(self, topLeftQModelIndex, bottomRightQModelIndex)

    def focusInEvent (self, eventQFocusEvent):
        self.focusKeyboardOn = False
        QtGui.QTableWidget.focusInEvent(self, eventQFocusEvent)

    def focusOutEvent (self, eventQFocusEvent):
        self.focusKeyboardOn = True
        QtGui.QTableWidget.focusOutEvent(self, eventQFocusEvent)

class QCustomWidget (QtGui.QWidget):
    def __init__(self, parent = None):
        super(QCustomWidget, self).__init__(parent)
        self.myQCustomTableWidget = QCustomTableWidget(self)
        self.myQLabel = QtGui.QLabel('Track edited data', self)
        myQVBoxLayout = QtGui.QVBoxLayout()
        myQVBoxLayout.addWidget(self.myQLabel)
        myQVBoxLayout.addWidget(self.myQCustomTableWidget)
        self.setLayout(myQVBoxLayout)
        self.connect(self.myQCustomTableWidget, QtCore.SIGNAL('currentKeyboardDataChanged'), self.setTrackData)
        self.myQCustomTableWidget.setItem(0, 0, QtGui.QTableWidgetItem('Test'))
        self.myQCustomTableWidget.setItem(1, 1, QtGui.QTableWidgetItem('Work'))

    def setTrackData (self, row, column, dataQTableWidgetItem):
        self.myQLabel.setText('Last updated\nRow : %d, Column : %d, Data : %s' % (row + 1, column + 1, str(dataQTableWidgetItem.text())))

if __name__ == '__main__':
    myQApplication = QtGui.QApplication(sys.argv)
    myQCustomWidget = QCustomWidget()
    myQCustomWidget.show()
    sys.exit(myQApplication.exec_())

注意:有一个条件会导致BUG:如果你在通过键盘编辑时使用 'QtGui.QTableWidgetItem.setText'。但如果你严格控制这种情况, 我建议你创建自己的小部件,并设置你自己的项目代理。(不过,这样做比较复杂…)


我不知道你单元格里的数据是什么。(是另一个自定义的 QWidget 还是普通的数据 QTableWidgetItem

无论如何,当用户编辑单元格时,你可以尝试用这个方法获取新值 QAbstractItemView.dataChanged (self, QModelIndex topLeft, QModelIndex bottomRight)。这个方法会返回被编辑的数据的位置,你可以通过 QTableWidgetItem QTableWidget.item (self, int row, int column) 来获取数据。(这就是你问的问题)但这个方法只在编辑结束后有效(而不是在编辑过程中)。

示例;

import sys
from PyQt4 import QtGui, QtCore

class QCustomTableWidget (QtGui.QTableWidget):
    def __init__ (self, parent = None):
        super(QCustomTableWidget, self).__init__(parent)
        # Setup row & column data
        listsVerticalHeaderItem = ['Device 1', 'Device 2', 'Device 3', 'Device 4', 'Device 5']
        self.setRowCount(len(listsVerticalHeaderItem))
        for index in range(self.rowCount()):
            self.setVerticalHeaderItem(index, QtGui.QTableWidgetItem(listsVerticalHeaderItem[index]))
        listsVerticalHeaderItem = ['Device 1', 'Device 2', 'Device 3', 'Device 4']
        self.setColumnCount(5)
        listsHorizontalHeaderItem = ['Option 1', 'Option 2']
        self.setColumnCount(len(listsHorizontalHeaderItem))
        for index in range(self.columnCount()):
            self.setHorizontalHeaderItem(index, QtGui.QTableWidgetItem(listsHorizontalHeaderItem[index]))

    def dataChanged (self, topLeftQModelIndex, bottomRightQModelIndex):
        row                  = topLeftQModelIndex.row()
        column               = topLeftQModelIndex.column()
        dataQTableWidgetItem = self.item(row, column)
        print '###### Data Changed  ######'
        print 'row    :', row + 1
        print 'column :', column + 1
        print 'data   :', dataQTableWidgetItem.text()
        self.emit(QtCore.SIGNAL('dataChanged'), row, column, dataQTableWidgetItem)
        QtGui.QTableWidget.dataChanged(self, topLeftQModelIndex, bottomRightQModelIndex)

class QCustomWidget (QtGui.QWidget):
    def __init__(self, parent = None):
        super(QCustomWidget, self).__init__(parent)
        self.myQCustomTableWidget = QCustomTableWidget(self)
        self.myQLabel = QtGui.QLabel('Track edited data', self)
        myQVBoxLayout = QtGui.QVBoxLayout()
        myQVBoxLayout.addWidget(self.myQLabel)
        myQVBoxLayout.addWidget(self.myQCustomTableWidget)
        self.setLayout(myQVBoxLayout)
        self.connect(self.myQCustomTableWidget, QtCore.SIGNAL('dataChanged'), self.setTrackData)

    def setTrackData (self, row, column, dataQTableWidgetItem):
        self.myQLabel.setText('Last updated\nRow : %d, Column : %d, Data : %s' % (row + 1, column + 1, str(dataQTableWidgetItem.text())))

if __name__ == '__main__':
    myQApplication = QtGui.QApplication(sys.argv)
    myQCustomWidget = QCustomWidget()
    myQCustomWidget.show()
    sys.exit(myQApplication.exec_())

QAbstractItemView.dataChanged (self, QModelIndex topLeft, QModelIndex bottomRight) 参考链接 : http://pyqt.sourceforge.net/Docs/PyQt4/qabstractitemview.html#dataChanged


祝好,

撰写回答