PDA

View Full Version : Custom widget table sort



giantdragon
10th June 2011, 00:21
I have QTableWidget with custom progress bars (derived from QWidget), inserted into table with setCellWidget. Each bar have "progress" property and I need to sort by it. I reimplemented "<" operator, but sorting doesn't work and operator "<" not even called.

Header:

bool operator < (const ProgressBar &other);
CPP:


bool ProgressBar::operator < (const ProgressBar &other)
{
return progress < other.progress;
}

wysota
10th June 2011, 00:30
What exactly are you "sorting"? How are you calling the sort? If you are trying to sort widgets then it won't work :) Well... actually it will sort them but nothing in Qt expects widgets to be sorted so if you're hoping for some automatic behaviour, nothing like that will happen.

giantdragon
10th June 2011, 00:39
Is it possible to sort QTableWidget by custom widget?

Santosh Reddy
10th June 2011, 01:43
Yes it is, One way to do so is to create a CustomTableWidgetItem like this


class CustomTableWidgetItem : public QWidget, public QTableWidgetItem
{
...
public:
virtual bool operator<(const QTableWidgetItem& other) const
{
; // re-implement this, as per you sorting requirement
}
...
}

CustomTableWidgetItem gives you an interface for both you Widget (QProgressBar in your case) and QTableWidgetItem

Warning: You need to properly implement operator<(), as the the parameter "other" is not guarantied to be a CustomTableWidgetItem (unless all the items in your QTableWidget are of type CustomTableWidgetItem)

You can also inherit CustomTableWidgetItem from QProgressBar instead of QWidget, it's up to you.

giantdragon
10th June 2011, 11:38
All elements in given column will be custom progress bars.
In operator "<" you pass "const QTableWidgetItem&", but I need to access to the custom progress bar's property, it seems that I need to cast "this" and "other" to custom progress bar type, but dynamic_cast or "(ProgressBar*) this" doen't work.

wysota
10th June 2011, 11:57
If you want to do it properly then store the value of progress in your model (aka item data) and apply a custom delegate that will render the looks of a progress bar to the element. Search the forum for information how to implement a custom delegate showing a progress bar.

Santosh Reddy
10th June 2011, 11:57
You don't need to cast this, you just to cast other, your operator will look like this

class CustomTableWidgetItem : public QProgressBar, public QTableWidgetItem{
...
}
bool CustomTableWidgetItem::operator<(const QTableWidgetItem& other) const
{
const QProgressBar *that = dynamic_cast<const QProgressBar *>(&other);
if(that != 0)
{
if(this->value() < that->value())
return true;
}
return false;
}

giantdragon
10th June 2011, 12:09
Sorting now works, thanks for your answer.
But another problem emerged - I use custom progress bar (not QProgressBar) and reimplemented paintEvent to draw my own progress bar. If I add my bar to table with "setCellWidget" function sorting works, but I see white area instead of progress indicator. If I add it with "setItem" function painting works well, but sorting doesn't work.

wysota
10th June 2011, 12:13
Then do it properly (see #6).

Santosh Reddy
10th June 2011, 12:24
You need to use both setItem(), and setCellWidget().
You need set the CustomTableWidgetItem on the table using setItem(), and use setCellWidget() somewhere in the ctor (or relevant method) of CustomTableWidgetItem

giantdragon
10th June 2011, 12:36
It now both paints and sorts. Thanks.

In my custom table's add method:


...
setCellWidget(i, 1, bar);
setItem(i, 1, bar);