Reputation: 48
I am fairly new to PyQt and I am making a GUI in PyQt4 and Python 2.7 that (among other things) controls the settings of a handful of micro-controllers. To easily populate and display the list of settings, and which controller they are from I have put it into a QTableWidget with the columns being the controllers and the rows being the settings (all controllers are simply duplicates of each other, though not all settings will be the same value from controller to controller).
The problem I am having is that when the user edits the cell I try to get that new value with
value = self.Settings1Table.item(n, s).text()
but that only retrieves the value that I placed in the cell during population, not the value that was just entered via the keyboard. I have read about a method currentText()
but from what I understand, that requires each cell to be its own widget, and I'm not sure how that is done.
The entire code is quite large, and I felt that it was unnecessary to post it in its entirety, but if more of the code is needed, I'll be happy to provide. Thank you for the help I hope is to come.
Edit: Here is the method that iterates through each item in the table, its supposed to get the current value, but right now only returns the value that I have set via item.setText(str) (needs to be the value that the user inputted via keyboard)
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")
The self.CheckHealth() is just error checking
Upvotes: 2
Views: 4853
Reputation: 3450
LAST UPDATED 8 / 19 / 2014 0 : 29
I don't really care about the event, since I am going to loop through the entire table, I do need the data changed by the keyboard instead of 'QtGui.QTableWidgetItem.setText' so yes
OK, It's possibly to create event then keyboard only, but your have to implement QtGui.QTableWidget.focusInEvent(self, eventQFocusEvent)
and QtGui.QTableWidget.focusOutEvent(self, eventQFocusEvent)
. So, please see ny example code, hope is help;
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_())
NOTE : It have 1 codition to have BUG: If your set by 'QtGui.QTableWidgetItem.setText' while edit via keyboard active. But if your strict it case, I suggest create your own widget and set item delegate your own. (But, very hardcore ...)
I don't know what is data in your cell what is it. (It's another custom QWidget
or it just normal data QTableWidgetItem
)
Anyway, when the user edits the cell your try to get that new value with this method QAbstractItemView.dataChanged (self, QModelIndex topLeft, QModelIndex bottomRight)
. This method return position of data has edited and your get data from index by use QTableWidgetItem QTableWidget.item (self, int row, int column)
. (That what your say it question) But this work only edit has close (Not during edit).
Example;
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)
Reference : http://pyqt.sourceforge.net/Docs/PyQt4/qabstractitemview.html#dataChanged
Regards,
Upvotes: 2