Issue
I'm trying to put together a simple table that shows my model's data. I need row selection behaviour so I set:
self.setSelectionBehavior(QAbstractItemView.SelectRows)
All is good until I implement selectionChanged()
which causes the redraw to get a bit confused every time a row is selected (cell's dont' seem to update their selection state). Here is some test code that causes the problem for me:
import sys
from PySide.QtGui import *
from PySide.QtCore import *
class Item( QStandardItem ):
def __init__( self, parent=None ):
super( Item, self).__init__( parent )
self.pixmap = QPixmap("colour.png")
#def data(self, role=Qt.UserRole + 1):
#'''with this method in place the cells get a checkbox and are not selectable'''
#return 'test'
class Model (QStandardItemModel):
def __init__( self, parent=None ):
super( Model, self).__init__( parent )
self.setHorizontalHeaderLabels(['a', 'b', 'c'])
self.init_data()
def init_data(self):
for row in range(0, 15):
for col in range(0, 10):
col_item = Item( '%s, %s' % (row, col) )
self.setItem(row, col, col_item)
class TableView( QTableView ):
def __init__( self, parent=None ):
super( TableView, self).__init__( parent )
model = Model()
self.setModel(model)
self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.setSelectionMode(QAbstractItemView.ContiguousSelection)
self.setMouseTracking(True)
def selectionChanged(self, selected, deselected):
print selected
if __name__ == '__main__':
app = QApplication([])
table = TableView()
table.show()
sys.exit(app.exec_())
I'm also a bit confused about why the cell's all get a checkbox and become un-selectable if the data()
method is implemented in the QStandardItem
. Can somebody please help?
Cheers, frank
Solution
You are overriding the QTableView
s selectionChanged
. That is (probably) used internally by the view and you prevent that. I am not sure why you would want to do that. You should use the selectionChanged
signal of the selectionModel()
for the view if you want to do custom things when the selection changes.
But if you insist on overriding selectionChanged
on TableView
at least call the parents function too, so that view could do its work:
class TableView( QTableView ):
def __init__( self, parent=None ):
super( TableView, self).__init__( parent )
model = Model()
self.setModel(model)
self.setSelectionBehavior(QAbstractItemView.SelectRows)
self.setSelectionMode(QAbstractItemView.ContiguousSelection)
self.setMouseTracking(True)
def selectionChanged(self, selected, deselected):
print selected
super(TableView, self).selectionChanged(selected, deselected)
But, you don't need to and you really shouldn't subclass a QTableView
just to set a few properties. You can do that for an instance. Actually, all your sub-classes are unnecessary. You could write that code like this:
import sys
from PySide.QtGui import *
from PySide.QtCore import *
if __name__ == '__main__':
app = QApplication([])
# create model
model = QStandardItemModel()
model.setHorizontalHeaderLabels(['a', 'b', 'c'])
# fill data
for row in range(15):
model.appendRow([QStandardItem('%d, %d' % (row, col)) for col in range(10)])
# create table view
table = QTableView()
# set parameters
table.setModel(model)
table.setSelectionBehavior(QAbstractItemView.SelectRows)
table.setSelectionMode(QAbstractItemView.ContiguousSelection)
table.setMouseTracking(True)
# show
table.show()
sys.exit(app.exec_())
As for overriding the data
method for the model: data
method is responsible for returning many different values depending on the role
that view asks. You are always returning "test"
for all of them. That is, to say the least, bad. If you want to create your own models, you should at least read about how models/views work in Qt. Official docs have a nice section about it. You can also find some decent video tutorials in the web.
Answered By - Avaris
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.