views:

666

answers:

3

I'm working a small qt app (using PyQt4) and I've come up with an idea but I'm unsure as to how to implement it. I have a QTableView that represents some data and I'd like to add another column to the QTableView that contains a checkbox control that could be wired up to some piece of the model. For example, something like this:

alt text

Note the Delete column has a checkbox widget for each row (although this is a web app, not a desktop Qt app, the principal is the same). Bonus points if I can select multiple rows, right click, and choose "Check/Uncheck Selected".

If any of this is unclear, drop a comment here and I'll clarify.

+1  A: 

In Qt/C++ you can create a delegate for custom items in a column. I would assume you can do something very similar in PyQt. See the following examples:

Star Delegate Example
Spin Box Delegate Example

Jesse
+3  A: 

You could also have a look at the QStandardItemModel, which gives you an interface to interact with items through a "checkable" state !

You could also inherit from QAbstractItemModel and use the role Qt::CheckStateRole...

Andy M
+1  A: 

Implementing your own table model is more work than using QStandardItemModel (as @Andy recommends), but it does give you a fine control over what you want to do, so I'll try to give you a summary of what to do. I assume you know all about Qt's documentation and PyQt's class documentation and can look up whatever classes you need. (I may be overexplaining if you already have a QTableView but better than leaving something out, I think.)

To get checkable states:

  • Create a subclass of QTableModel.
    • Select some data structure to store the contents of your rows. This can be pretty simple (a big internal list), or as complex as a SQL database (in which case see QSqlTableModel instead).
    • Override rowCount, columnCount, data, and setData.
      • rowCount and columnCount correspond fairly directly to what you use for a data model. If you basically are using a 2D array (or list of lists), they can be as short as one-liners.
      • data is where things get interesting. Item models store several different fields (which Qt calls roles) and what data returns depends on what role is being asked for. Note that I talk about the data types of what's returned but it always needs to be wrapped into QVariant.
        • Qt.DisplayRole is whatever text is displayed in the cells of the table. This is your actual data, and is by far the common case (so that this is the default role).
        • Qt.CheckStateRole is a boolean. Returning Qt.Checked will display a checked check-box, and Qt.Unchecked will return an unchecked one. If all you want a column to contain is check-boxes only handle this role.
        • The other roles are useful for icons, for background colors, and a number of other features but these.
        • Any unhandled role should return a QVariant.
      • setData is symmetric to data. You should handle the roles you handle in data: Qt.DisplayRole for the actual data, and Qt.CheckStateRole for the checkboxes.

To allow multiple selection of rows and columns and cells. To do that you want to understand selection models. The short version is:

  • Set the selection mode on your table view: view.setSelectionMode( QAbstractItemView.ContiguousSelection). This will let you highlight contiguous cells. You can highlight arbitrary cells as well: see QAbstractView.SelectionMode.
  • To determine which cells are actually selected following an action ask the table view for its selection model (note the 'l'): view.selectionModel().selectedIndexes(). You can iterate through these with a for loop.

To allow right-clicking:

  • Override your view's contextMenuEvent.
  • Create a QMenu and connect it to whatever slots you need.

For a more in-depth understanding read the Qt guide to Model/View if you haven't already. And definitely look at the Qt item view examples. Many of the ones describe are implemented in PyQt in much less code (including the two @Jesse mentions), and the tree model examples carry over to tables but with much less work (you need to implement much less, as described above.)

quark