How do I Color a QTableView row in PyQt4

M

Mel

I am currently porting an SQL centered Visual Basic application to run
on Linux, Python, and Qt4. Currently I am stumped on changing row
colors in the QTableView widget. My test code is based on code from
the PyQt4 examples and looks like this:

*** Start Code ***

import sys
from PyQt4 import QtCore, QtGui, QtSql

import connection


class CustomSqlModel(QtSql.QSqlQueryModel):
def data(self, index, role):
value = QtSql.QSqlQueryModel.data(self, index, role)
if value.isValid() and role == QtCore.Qt.DisplayRole:
if index.column() == 0:
return QtCore.QVariant(value.toString().prepend("#"))
elif index.column() == 2:
return QtCore.QVariant(value.toString().toUpper())
if role == QtCore.Qt.TextColorRole and index.column() == 1:
return QtCore.QVariant(QtGui.QColor(QtCore.Qt.blue))
return value

def initializeModel(model):
model.setQuery("SELECT * FROM WaterOrder Where DateCanceled is
NULL AND ActDateTimeOff is NULL and ActDateTimeOn is NOT NULL")

offset = 0
views = []

def createView(title, model):
global offset, views

view = QtGui.QTableView()
views.append(view)
view.setModel(model)
view.setWindowTitle(title)
for i in range(model.columnCount()):
view.resizeColumnToContents(i)
view.setAlternatingRowColors(1)

view.move(100 + offset, 100 + offset)
offset += 20
view.show()


if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
if not connection.createConnection():
sys.exit(1)

customModel = CustomSqlModel()
initializeModel(customModel)
createView(QtCore.QObject.tr(customModel, "Running Water"),
customModel)

sys.exit(app.exec_())

*** End Code ***


Column 18 in the table shows a number from 1 to 3. I would like to
change the color of the row based on the value in column 18 but I have
not been able to find any resources that show me how. Can anyone lend
a hand?

Thanks,
Mel
 
D

David Boddie

I am currently porting an SQL centered Visual Basic application to run
on Linux, Python, and Qt4. Currently I am stumped on changing row
colors in the QTableView widget. My test code is based on code from
the PyQt4 examples and looks like this:

*** Start Code ***

import sys
from PyQt4 import QtCore, QtGui, QtSql

import connection


class CustomSqlModel(QtSql.QSqlQueryModel):
def data(self, index, role):
value = QtSql.QSqlQueryModel.data(self, index, role)
if value.isValid() and role == QtCore.Qt.DisplayRole:
if index.column() == 0:
return QtCore.QVariant(value.toString().prepend("#"))
elif index.column() == 2:
return QtCore.QVariant(value.toString().toUpper())
if role == QtCore.Qt.TextColorRole and index.column() == 1:
return QtCore.QVariant(QtGui.QColor(QtCore.Qt.blue))
return value

[Snipping the rest of the code to keep this post short.]
Column 18 in the table shows a number from 1 to 3. I would like to
change the color of the row based on the value in column 18 but I have
not been able to find any resources that show me how. Can anyone lend
a hand?

It's interesting to see that you subclassed QSqlQueryModel instead of
using a custom delegate to display the data. It's usually recommended
that you subclass QItemDelegate if you want to customize the way items
are represented, but you can also customize the model if you want.

What you can do is to check to see if the requested role is the
Qt.BackgroundRole and, if so, query the base class for the data in
column 18 in the same row. Then you can supply a different colour
(as a brush, actually) depending on the value you obtained.

if role == QtCore.Qt.BackgroundRole:
# Get the data from column 18.
column18_data = index.sibling(index.row(), 18).data()
# The data is stored in a QVariant, so we unpack it.
integer_value = column18_data.toInt()[0] # just the value
# Look up the associated color in a dictionary which you
# have already defined, and return it.
color = self.colors.get(integer_value, self.default_color)
return QtCore.QVariant(QtGui.QBrush(color))

You might also find the following pages useful:

http://www.riverbankcomputing.com/Docs/PyQt4/html/qt.html#ItemDataRole-enum
http://doc.trolltech.com/4.2/model-view-model.html

Good luck!

David
 
D

David Boddie

[Following up my own post.]

It's interesting to see that you subclassed QSqlQueryModel instead of
using a custom delegate to display the data. It's usually recommended
that you subclass QItemDelegate if you want to customize the way items
are represented, but you can also customize the model if you want.

On reflection, I think subclassing the model is probably the right
thing to do here. Delegates are much more useful if you want to
substantially alter the appearance of items, but that's not what you're
trying to do here.

David
 
M

Mel

I am currently porting an SQL centered Visual Basic application to run
on Linux, Python, and Qt4. Currently I am stumped on changing row
colors in the QTableView widget. My test code is based on code from
the PyQt4 examples and looks like this:
*** Start Code ***
import sys
from PyQt4 import QtCore, QtGui, QtSql
import connection
class CustomSqlModel(QtSql.QSqlQueryModel):
def data(self, index, role):
value = QtSql.QSqlQueryModel.data(self, index, role)
if value.isValid() and role == QtCore.Qt.DisplayRole:
if index.column() == 0:
return QtCore.QVariant(value.toString().prepend("#"))
elif index.column() == 2:
return QtCore.QVariant(value.toString().toUpper())
if role == QtCore.Qt.TextColorRole and index.column() == 1:
return QtCore.QVariant(QtGui.QColor(QtCore.Qt.blue))
return value

[Snipping the rest of the code to keep this post short.]
Column 18 in the table shows a number from 1 to 3. I would like to
change the color of the row based on the value in column 18 but I have
not been able to find any resources that show me how. Can anyone lend
a hand?

It's interesting to see that you subclassed QSqlQueryModel instead of
using a custom delegate to display the data. It's usually recommended
that you subclass QItemDelegate if you want to customize the way items
are represented, but you can also customize the model if you want.

What you can do is to check to see if the requested role is the
Qt.BackgroundRole and, if so, query the base class for the data in
column 18 in the same row. Then you can supply a different colour
(as a brush, actually) depending on the value you obtained.

if role == QtCore.Qt.BackgroundRole:
# Get the data from column 18.
column18_data = index.sibling(index.row(), 18).data()
# The data is stored in a QVariant, so we unpack it.
integer_value = column18_data.toInt()[0] # just the value
# Look up the associated color in a dictionary which you
# have already defined, and return it.
color = self.colors.get(integer_value, self.default_color)
return QtCore.QVariant(QtGui.QBrush(color))

You might also find the following pages useful:

http://www.riverbankcomputing.com/D...//doc.trolltech.com/4.2/model-view-model.html

Good luck!

David

Thanks David, that did work as I had hoped. I just need to work on
the colors a bit and make them more appealing.

Here is my final code that works for the custom Sql Model.

class CustomSqlModel(QtSql.QSqlQueryModel):
def data(self, index, role):
value = QtSql.QSqlQueryModel.data(self, index, role)
if value.isValid() and role == QtCore.Qt.DisplayRole:
if index.column() == 0:
return QtCore.QVariant(value.toString().prepend("#"))
elif index.column() == 2:
return QtCore.QVariant(value.toString().toUpper())
if role == QtCore.Qt.TextColorRole and index.column() == 1:
return QtCore.QVariant(QtGui.QColor(QtCore.Qt.blue))
if role == QtCore.Qt.BackgroundRole:

# Get the data from column 18.

column18_data = index.sibling(index.row(), 18).data()

# The data is stored in a QVariant, so we unpack it.

integer_value = column18_data.toInt()[0] # just the value

# Look up the associated color in a dictionary which you

# have already defined, and return it.
if integer_value == 1:

return
QtCore.QVariant(QtGui.QBrush(QtGui.QColor(QtCore.Qt.red)))
if integer_value == 2:

return
QtCore.QVariant(QtGui.QBrush(QtGui.QColor(QtCore.Qt.yellow)))
if integer_value == 3:

return
QtCore.QVariant(QtGui.QBrush(QtGui.QColor(QtCore.Qt.green)))
return value


Mel
 
M

Mel

Now that I can change the row colors of QTableView when loading data I
now need to be able to set the color of the row at anytime. I've been
trying by using an item delegate but I'm not sure if I'm using it
correctly. Would I try and set an item delegate for the row and
change the background color that way? An example or a link to easy to
understand documentation on changing a row color for an object based
on QTableView using QSqlQueryModel as a model would be greatly
appreciated. I'm still a bit confused in Qt4.

Mel
 
D

David Boddie

<posted & mailed>

On Friday 02 March 2007 21:55, Mel wrote:

[This message is a bit old now. Still...]
Now that I can change the row colors of QTableView when loading data I
now need to be able to set the color of the row at anytime. I've been
trying by using an item delegate but I'm not sure if I'm using it
correctly.

Thinking about it a bit, I'd probably avoid using a delegate for this.
Ideally, you want to influence the BackgroundRole for each item in
the row somehow.
Would I try and set an item delegate for the row and
change the background color that way? An example or a link to easy
to understand documentation on changing a row color for an object
based on QTableView using QSqlQueryModel as a model would be greatly
appreciated. I'm still a bit confused in Qt4.

That's a very specific request! Anyway, using QTableView and
QSqlQueryModel together is quite common, but we can look at a way
to achieve this.

One way would be to store a list of colors in the custom model, or
use another database table to hold them, and access these whenever
you need to return BackgroundRole data for any item in a row.

You could lazily initialize these colors by setting each one when the
corresponding row is accessed for the first time, and only updating
it when the relevant item in the row is modified.

David
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top