Creating a calendar using QTableWidget with QItemDelegate
-
You have to subclass QStyledItemDelegate. You receive the QPainter to use in the paint function (it's the first argument of the function)
The delegate will be called for each cell since each cell can contain something different.
-
Hi and sorry for the belated response.
Well, I subclassed QStyledItemDelegate now, reimplemented the paint function and tried to display a string on the top left corner of each cell in column 2 of a table. To ensure that only column 2 uses the custom delegate, I set the delegate only for column 2.
This is how my paint function looks like:
[code]
void testDelegate::paint(QPainter *pPainter, const QStyleOptionViewItem &soviOption, const QModelIndex &miIndex) const
{
pPainter->drawText(QRect(0,0,50,20), "TestString");
QStyledItemDelegate::paint(pPainter, soviOption, miIndex);
return;
}
[/code]
Well, the interesting thing now is, that the strings (5 strings because I have 5 cells in column 2) are all positioned on the top left corner of the top left cell (col 1, row 1). That is suspicious, because the coordinates should be relative for each cell...
Also , when I manually change the window size, the table and its cells adjust to the window but the strings don't move! Hence, they are not stored into their corresponding cells but hover them as a z-stack... They don't respect cell borders...
What's the matter with that behaviour??Instead, when I use the QRect from the option variable of the argument list of the paint function, I get the results I expected!
[code]
pPainter->drawText(soviOption.rect, "TestString");
[/code]
Where is the difference between these two methods and why does the first example position the data "over" the cells without respecting their borders and absolute positioning at the top left corner of the whole table?? -
Because the same painter is used to paint the whole widget. The option parameter gives you all the information needed to paint one cell.
-
But option.rect also only returns a QRect, doesn't it? So, where is the difference between the following examples:
[code]
painter->drawText(option.rect, "TestString"); // assuming that option.rect returns a QRect(100,50,20,20)
[/code][code]
painter->drawText(QRect(100,50,20,20), "TestString");
[/code]
For the compiler, it should be tha same, isn't it? -
The rect changes for each cell
-
yeah I know, I catched the coordinates of option.rect for the 5 cells with qDebug:
x is alway 185, y = index.row * 51, width is always 91 and height is always 50.Hence, the following two methods do exactly the same positioning (I tested it):
[code]
painter->drawText(option.rect, "TestString");
[/code][code]
painter->drawText(QRect(185,index.row()*51,91,50), "TestString");
[/code]BUT the difference is, that the first example stores the strings INTO the cells (changing window size also lets the strings move with its corresponding cells). The second example doesn't. In the second example, the strings are layed over the table, they don't belong to a cell and fly over their borders when resizing the window... They are like ghosts!
Can you explain this behaviour?
-
Again: option.rect changes for each cell. It will be adapted to changes of column size, row size etc.
-
Maybe one last Question:
Does it make any difference to the appeareance when using a custom item delegate in combination with QTableWidgetItem instead of using the custom delegate with plain cells? Does the custom delegate also effect to QTableWidgetItems or will they use their own display methods? -
No, these are just items holding data, the delegate will act just the same
-
Ah, I see. So a delegate is really just a layer that is not interested in data that is already stored into a table. So I think it will not be possible for me to place data via delegate that should be clickable like a link, right? The click would go "through" the delegate and would only hit the underlying QTableWidgetItem...
-
eventFilter comes to mind to handle that
-
Well, maybe I have one more question:
In my code, I subclass QItemDelegate but I only reimplement the paint function. So the editor behaviour should be the same as in default delegate mode.What I'm asking myself now is, how the delegate (which, in my eyes, can be seen as a layer of data over the table) interacts with QTableWidgetItems. For a example, I inserted QTableWidgets in every table cell with a text "itemText". Also, I used the custom QItemDelegate and let the paint function paint a text "delegateText" over every cell.
The result is (as expected), that the "delegateText" is displayed over the "itemText". So the delegate is like a layer that is not interested in what the cell does.BUT, what happens if I try to edit the QTableWidgetItem by double click? As expected, an editable cursor appears. But is this now the editor of the QTableWidgetItem or is it the editor of the QItemDelegate ?? And what would happen if I disable one of them?
-
The QTableWidgetItem is essentially a data container, it doesn't know about any editor.
It's the delegate that uses a factory that will return the corresponding editor based on the item content type.