How do I Color a QTableView row in PyQt4

Discussion in 'Python' started by Mel, Feb 28, 2007.

  1. Mel

    Mel Guest

    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
    Mel, Feb 28, 2007
    #1
    1. Advertising

  2. Mel

    David Boddie Guest

    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/Docs/PyQt4/html/qt.html#ItemDataRole-enum
    http://doc.trolltech.com/4.2/model-view-model.html

    Good luck!

    David
    David Boddie, Mar 1, 2007
    #2
    1. Advertising

  3. Mel

    David Boddie Guest

    [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
    David Boddie, Mar 1, 2007
    #3
  4. Mel

    Mel Guest

    On Feb 28, 5:08 pm, David Boddie <> wrote:
    > 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/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
    Mel, Mar 1, 2007
    #4
  5. Mel

    Mel Guest

    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
    Mel, Mar 2, 2007
    #5
  6. Mel

    David Boddie Guest

    <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
    David Boddie, Mar 13, 2007
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. G. Whiz
    Replies:
    1
    Views:
    2,845
  2. =?Utf-8?B?aWdvdHlvdXJkb3RuZXQ=?=

    change row color of empty row

    =?Utf-8?B?aWdvdHlvdXJkb3RuZXQ=?=, Oct 19, 2006, in forum: ASP .Net
    Replies:
    3
    Views:
    442
    Walter Wang [MSFT]
    Oct 24, 2006
  3. wgw
    Replies:
    1
    Views:
    455
  4. D
    Replies:
    0
    Views:
    198
  5. Kamaljeet Saini
    Replies:
    0
    Views:
    389
    Kamaljeet Saini
    Feb 13, 2009
Loading...

Share This Page