PDA

View Full Version : QTableView Repaint/Refresh



millsks
10th January 2008, 14:34
I have a qtableview connected to my model and everything is working the way it is supposed to (well as far as I know). The only issue that I am having is a cosmetic one. Whenever I scroll or mouseover the qtableview the grdilines, and even the alternating row colors, seems to disappear. The issue also only arises if I am spanning rows and/or columns.

Is there a method that I have to reimplement in the model to stop this from happening?

jpn
10th January 2008, 14:36
This could be a bug in Qt. Which exact version of Qt are you using?

millsks
10th January 2008, 14:41
I am using v4.3.0

millsks
10th January 2008, 14:49
Here is a screenshot to try and explain a little more what it is doing.

jpn
10th January 2008, 14:52
Does something minimal like this work properly?


#include <QtGui>

int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QTableWidget t(3, 2);
t.setSpan(0, 0, 1, 2);
t.setSpan(1, 0, 2, 1);
t.show();
return a.exec();
}

millsks
10th January 2008, 16:46
yes that worked, but still not sure why mine is acting differently. Ill attach a portion of my model code just in case you may want to take a look at it at a deeper level.

FYI though this is PyQT code, but the ideology is the same.



class PyTableModel(QAbstractTableModel):
def __init__(self, xmlData=None, numPasses=1):
super(PyTableModel, self).__init__()

self.alternateColor_Header = True
self.alternateColor_Data = True

self.lstPassItems = [...left out to save space...]

self.chkPassItems = [1]*len(self.lstPassItems)
self.numPasses = numPasses*3
self.lstPasses = range(numPasses)
self.passData = [[[float('%.3F' % (random.randint(0.00, 1000.00)*random.random())),
float('%.3F' % (random.randint(0.00, 1000.00)*random.random())),
float('%.3F' % (random.randint(0.00, 1000.00)*random.random()))]]]

self.palette = QPalette()

self.initPassData()

print len(self.passData)
print len(self.passData[0])
print len(self.passData[0][0])

def initPassData(self):
for x in range(self.numPasses/3):
for y in range(len(self.lstPassItems)):
self.passData[x].append([float('%.3F' % (random.randint(0.00, 1000.00)*random.random())),
float('%.3F' % (random.randint(0.00, 1000.00)*random.random())),
float('%.3F' % (random.randint(0.00, 1000.00)*random.random()))])

self.passData.append([])

def rowCount(self, index=QModelIndex()):
return len(self.lstPassItems)+2

def columnCount(self, index=QModelIndex()):
return self.numPasses+1

def data(self, index, role=Qt.DisplayRole):
if 0 == index.row() and 0 == index.column():
if role == Qt.DisplayRole:
return QVariant('Pass')
if role == Qt.TextAlignmentRole:
return QVariant(Qt.AlignTop)
if role == Qt.BackgroundColorRole:
return QVariant(QColor(0,0,0))
if role == Qt.FontRole:
return QVariant(QFont('', 16, QFont.Bold))
if role == Qt.ForegroundRole:
return QVariant(QColor(255,255,255))

if 0 == index.row() and index.column() > 0:
if index.column() % 3 == 1:
self.alternateColor_Header = not self.alternateColor_Header

if role == Qt.DisplayRole:
if 1 == (index.column()%3):
return QVariant(self.lstPasses[index.column()/3]+1)
else:
return QVariant()
if role == Qt.TextAlignmentRole:
return QVariant(Qt.AlignCenter)
if role == Qt.BackgroundColorRole:
if self.alternateColor_Header:
return QVariant(QColor(0,0,0))
else:
return QVariant(QColor(50,50,50))
if role == Qt.FontRole:
return QVariant(QFont('', 8, QFont.Bold))
if role == Qt.TextColorRole:
return QVariant(QColor(255,255,255))

if 1 == index.row() and (index.column() != 0 and 0 == (index.column()%3)):
if role == Qt.DisplayRole:
return QVariant('Tolerance')
if role == Qt.TextAlignmentRole:
return QVariant(Qt.AlignCenter)
if role == Qt.BackgroundColorRole:
return QVariant(self.palette.color(QPalette.Background).d arker(200))
if role == Qt.FontRole:
return QVariant(QFont('', 8, QFont.Normal))
elif 1 == index.row() and (index.column() != 0 and 1 == (index.column()%3)):
if role == Qt.DisplayRole:
return QVariant('Value')
if role == Qt.TextAlignmentRole:
return QVariant(Qt.AlignCenter)
if role == Qt.BackgroundColorRole:
return QVariant(self.palette.color(QPalette.Background).d arker(200))
if role == Qt.FontRole:
return QVariant(QFont('', 8, QFont.Normal))
elif 1 == index.row() and (index.column() != 0 and 2 == (index.column()%3)):
if role == Qt.DisplayRole:
return QVariant('Display')
if role == Qt.TextAlignmentRole:
return QVariant(Qt.AlignCenter)
if role == Qt.BackgroundColorRole:
return QVariant(self.palette.color(QPalette.Background).d arker(200))
if role == Qt.FontRole:
return QVariant(QFont('', 8, QFont.Normal))

if 1 <= index.column() < self.numPasses+1 and 2 <= index.row():
if (index.column()-1) % 3 == 0:
self.alternateColor_Data = not self.alternateColor_Data
if role == Qt.DisplayRole:
return QVariant(self.passData[(index.column()-1)/3][index.row()-2][(index.column()-1)%3])
if role == Qt.BackgroundColorRole:
if self.alternateColor_Data:
return QVariant(self.palette.color(QPalette.Background).d arker(25))
else:
return QVariant(self.palette.color(QPalette.Background).d arker(105))
return QVariant()

item = self.lstPassItems[index.row()-2]

if 0 == index.column() and 2 <= index.row():
if role == Qt.DisplayRole:
return QVariant(item[0])
if role == Qt.TextAlignmentRole:
return QVariant(Qt.AlignLeft)
if role == Qt.BackgroundColorRole:
return QVariant(self.palette.color(QPalette.Background).d arker(125))
if role == Qt.FontRole:
return QVariant(QFont('', 8, QFont.Normal))
if role == Qt.ToolTipRole:
return QVariant(item[1])
if role == Qt.CheckStateRole:
if self.chkPassItems[index.row()-2] == 1:
return QVariant(Qt.Checked)
else:
return QVariant(Qt.Unchecked)

return QVariant()

def setData(self, index, value=QVariant(), role=Qt.EditRole):
if index.isValid() and (index.column() == 0 and index.row() >= 2):
if role == Qt.CheckStateRole:
if self.chkPassItems[index.row()-2] == 0:
self.chkPassItems[index.row()-2] = 1
else:
self.chkPassItems[index.row()-2] = 0
if role == Qt.EditRole:
try:
if value.toString() != '':
self.passData[(index.column()-1)/3][index.row()-2][(index.column()-1)%3] = float('%.3F' % float(value.toString()))
print 'Pass Data:', self.passData[(index.column()-1)/3][index.row()-2][(index.column()-1)%3]
print 'Value:', float('%.3F' % float(value.toString()))
except ValueError, ve:
pass

return True

def flags(self, index):
if 0 == index.column() and 2 <= index.row():
return Qt.ItemIsUserCheckable|Qt.ItemIsSelectable|Qt.Item IsEnabled
if 1 <= index.column() < self.numPasses+1:
if 0 <= index.row() < 2:
return Qt.ItemIsSelectable|Qt.ItemIsEnabled
return Qt.ItemIsEditable|Qt.ItemIsEnabled|Qt.ItemIsSelect able
else:
if index.row() <= 1 >= index.column():
return Qt.ItemIsEnabled
return Qt.ItemIsSelectable|Qt.ItemIsEnabled

def headerData(self, section, orientation, role=Qt.DisplayRole):
return QVariant()

millsks
10th January 2008, 16:52
Also here is the class that I wrote that subclassed the QTableView.



class PyTableView(QTableView):
def __init__(self, parent=None):
super(PyTableView, self).__init__(parent)

self.model = PyTableModel(numPasses=5)

self.setModel(self.model)
self.resizeColumnToContents(0)

self.setSpan(0,0,2,1)
for col in range(self.model.columnCount())[1:]:
self.setSpan(0,((col*3)-3)+1,1,3)

self.horizontalHeader().hide()
self.verticalHeader().hide()

self.setRowHeight(0,25)
self.setRowHeight(1,25)

p = self.palette()
p.setColor(QPalette.AlternateBase, p.color(QPalette.AlternateBase).darker(105))

for row in range(self.model.rowCount())[2:]:
self.setRowHeight(row,20)

self.connect(self, SIGNAL('clicked(const QModelIndex &)'), self.testTable)

self.setAlternatingRowColors(True)
self.setAutoFillBackground(True)
self.setAutoScroll(True)
self.setWindowTitle('PyTableView')
self.resize(800,500)
self.show()

def testTable(self, index):
if index.column() == 0 and index.row() >= 2:
self.model.setData(index, role=Qt.CheckStateRole)
if index.column() > 0 and index.row() >= 2:
self.model.setData(index)
if index.column() > 0 and index.row() == 0:
col_multiplier = int(self.model.data(self.model.index(index.row(), index.column()), Qt.DisplayRole).toString())
print self.model.data(self.model.index(index.row(), index.column()), Qt.DisplayRole).toString()
print '-'*50
print 'Col:', index.column()*col_multiplier
print '-'*50

def closeEvent(self, closeEvt):
for row in range(self.model.rowCount(self.model.index(0,0)))[2:]:
if self.model.data(self.model.index(row,0), Qt.CheckStateRole).toString() == '2':
print row, self.model.data(self.model.index(row,0), Qt.DisplayRole).toString()

jpn
10th January 2008, 17:09
Model's data() should at least check index validity. Also, you could also try temporarily disabling that palette adjustment.

millsks
10th January 2008, 17:15
ill put the index validity checker in there, but I the problem was there before I inserted the palette code.

millsks
10th January 2008, 17:18
inserted index.isValid() at the right spots, but still no go. im beginning to wonder if it has something to do with a dataChanged signal and/or a paintEvent.