3

So I have been writing a Sudoku game in C++. I have most of the game logic done and tested, but I wanted to use Qt on top of it for the GUI. I was trying to figure out the best way to work with the Qt classes for my needs.

As a test, I played around with QAbstractTableModel. I subclassed it and had it access my existing data model and my existing controllers. For now I am using QTableView to get basic rendering of the Sudoku board and basic "editing" (you can just change any value). It looks nothing like what I want, but the functionality is all there (or can be added).

I wanted to make a data model and controllers to modify it all in C++, without depending on a framework. Then I wanted to just have Qt sit on top. So I have this working, and here is a quick "diagram" of how these things communicate at a high level

QTableView?
    ^
    |
    v
PuzzleModel : QAbstractTableModel
             ^              |
             |              |_____________
             |                            v
Real data model classes <------------ Controllers

My question is, how can I modify QTableView or should I create my own view or QWidget in order to display the data the way I want?

Ideally, I'd like to display a fixed size table (no headers, no resizing), and disallow multi-selecting. There are some customizations on how I'd render various font styles/colors, but I think I can handle that pretty easily. I'd also like to render each cell as either a number, or like this for "marks":

*-------------*         *-------------*
|  1   2   3  |         |   ******    |
|  4       6  |         |        *    |
|      8   9  |         |        *    |
*-------------*         *-------------*

So clearly I can't continue using QTableView out of the box. Do I create my own QStyledItemDelegate and still use QTableView? Do I need to create a whole Widget? If I create

Just looking for some advice/direction from someone who knows the capabilities of the various Qt classes.

Matt
  • 5,478
  • 9
  • 56
  • 95

1 Answers1

4

You have two options:

  1. Continue to use QTableView and your QAbstractTableModel, and subclass QStyledItemDelegate to render the cells exactly how you want them. You can't change the inter-cell painting that way, though.

    Note, however, that you can achieve a lot of what you want (fonts, colors) by reacting to more Qt::ItemDataRoles from your model's data() implementation.

  2. Write a custom widget and use a custom data provider interface. Let me stress that: don't continue to use QAbstractTableModel when you implement your own SudokuWidget. It's much simpler for everyone that way (QAbstractItemModel is both way too abstract and way too specialised for the case of item views to be useful as a general data provider interface).

My advice is to go with (2). Interview is overrated.

Marc Mutz - mmutz
  • 24,485
  • 12
  • 80
  • 90
  • Okay, number 2 sounds like a good option (it seemed like I would need to go that route). Should I use something like `QGraphicsView` and `QGraphicsScene` (or some other `QGraphics`* class) to derive from? Or just the basic `QWidget`? Or something else entirely. I don't want to reinvent the wheel so I'd like to figure out the best starting point. And it would be nice if I got some things like selection for free as I did with `QTableView`. – Matt Apr 30 '11 at 17:11
  • @Matt: I'm a traditionalist. If there's no strong advantage to using a [scene graph](http://en.wikipedia.org/wiki/Scene_graph) (which is what `QGraphicsView` is), I don't. One thing to keep in mind is that if you create a custom widget with `QLineEdit`s as the entry fields, you'll get layouting and accessibility for free. Not so with `QGraphicsView`. That said, if you want to explore new things, you can try writing your UI in [QML](http://doc.trolltech.com/latest/qtquick.html). It's enough of a toy example (no offense!) that the limitations of Qt-4.7's QML implementation aren't an issue. – Marc Mutz - mmutz Apr 30 '11 at 17:24
  • Well, I had originally wanted to avoid doing too much "Qt-specific" stuff, but I did what seemed to be "easier" at the time. I think I'll avoid the Graphics view. However, I did come across this example: [link](http://code.google.com/p/sudoku-solver-qt/source/browse/trunk/src/SudokuDiagram.cpp) and I'm thinking I may just start with the `QTableView` and resize things and hide the headers as I need. If I can get darker borders on the 9 main squares too that would be great. Add a `QStyledItemDelegate` and I should be good. Except that code uses `QTableWidget`, but I think `QTableView` works – Matt Apr 30 '11 at 17:33
  • I'm accepting your answer for option 1. Since I can also just subclass the QTableView and get some of the other things I want. Thanks! – Matt Apr 30 '11 at 18:58