468,133 Members | 1,165 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,133 developers. It's quick & easy.

How do I Color a QTableView row in PyQt4

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

Feb 28 '07 #1
5 11041
On Wednesday 28 February 2007 18:55, Mel wrote:
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/Do...mDataRole-enum
http://doc.trolltech.com/4.2/model-view-model.html

Good luck!

David
Mar 1 '07 #2
[Following up my own post.]

On Thursday 01 March 2007 01:08, David Boddie wrote:
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
Mar 1 '07 #3
Mel
On Feb 28, 5:08 pm, David Boddie <d...@boddie.org.ukwrote:
On Wednesday 28 February 2007 18:55, Mel wrote:
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/Do...iew-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.Q t.red)))
if integer_value == 2:

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

return
QtCore.QVariant(QtGui.QBrush(QtGui.QColor(QtCore.Q t.green)))
return value
Mel

Mar 1 '07 #4
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

Mar 2 '07 #5
<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
Mar 13 '07 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Harshad | last post: by
3 posts views Thread by Tina I | last post: by
25 posts views Thread by Daniel Jonsson | last post: by
2 posts views Thread by Pradnyesh Sawant | last post: by
2 posts views Thread by Glen | last post: by
2 posts views Thread by Pradnyesh Sawant | last post: by
2 posts views Thread by jiang.haiyun | last post: by
reply views Thread by ilochab | last post: by
1 post views Thread by gcdp | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.