formatting a QTableView header
-
My model is defined like this:
QAbstractItemModel *m_model; // the main model
But it's initialized like this:
DeviceModel::DeviceModel(QObject *parent) : QObject(parent), m_model(new QStandardItemModel(this)) { QString qs; QStringList qsl; m_model->insertColumns(0, TAG_NBRTAGS); m_model->setHeaderData(TAG_SERIALNUMBER, Qt::Horizontal, tr("Serial Number"), Qt::DisplayRole); m_model->setHeaderData(TAG_MACADDRESS, Qt::Horizontal, tr("MAC Address"), Qt::DisplayRole); m_model->setHeaderData(TAG_DEVICENAME, Qt::Horizontal, tr("Device Name"), Qt::DisplayRole); m_model->setHeaderData(TAG_SERIALNUMBER, Qt::Horizontal, QBrush(Qt::red), Qt::BackgroundRole);
Note the use of the QStandardItemModel in the c'tor. (I think VRonin gave me this code, way back when.)
Not sure if this is what you're asking for...
Moderatorswrote on 3 Nov 2018, 15:59 last edited by kshegunov 11 Mar 2018, 16:00Yes, it is, but only partially. What does your
DeviceModel::headerData
contain? Does it just delegate to theQStandartItemModel
's method? -
wrote on 3 Nov 2018, 16:03 last edited by
I'm not doing anything with the header except what I posted above. DeviceModel is my own class that has the actual Qt model as a member:
class DeviceModel : public QObject { Q_OBJECT private: QAbstractItemModel *m_model; // the main model
-
I'm not doing anything with the header except what I posted above. DeviceModel is my own class that has the actual Qt model as a member:
class DeviceModel : public QObject { Q_OBJECT private: QAbstractItemModel *m_model; // the main model
@mzimmers said in formatting a QTableView header:
I'm not doing anything with the header except what I posted above. DeviceModel is my own class that has the actual Qt model as a member.
Indeed. My bad, sorry. It's rather odd. As far as I can tell this should be enough to have your header have a red background. As a follow up question: Do you use style sheets?
-
@mzimmers said in formatting a QTableView header:
I'm not doing anything with the header except what I posted above. DeviceModel is my own class that has the actual Qt model as a member.
Indeed. My bad, sorry. It's rather odd. As far as I can tell this should be enough to have your header have a red background. As a follow up question: Do you use style sheets?
wrote on 3 Nov 2018, 16:06 last edited by@kshegunov said in formatting a QTableView header:
As a follow up question: Do you use style sheets?
No, not in this app.
-
@kshegunov said in formatting a QTableView header:
As a follow up question: Do you use style sheets?
No, not in this app.
Moderatorswrote on 3 Nov 2018, 16:13 last edited by kshegunov 11 Mar 2018, 16:14I just tested a project of mine, and it works correctly. Here's what I did:
#include <QBrush> QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role) const { if (/*role != Qt::DisplayRole || */orientation != Qt::Horizontal || section > columnCount()) return QVariant(); if (role == Qt::DisplayRole) return columns.byIndex(section).displayName(); if (role == Qt::BackgroundRole) return QBrush(Qt::red); return QVariant(); }
I observe the background of the table view's header to be red. It's really odd why it doesn't work for you. Can you retrieve the header data just after you've set it to the model to see if it's correctly stored? I.e.
m_model->setHeaderData(TAG_SERIALNUMBER, Qt::Horizontal, QBrush(Qt::red), Qt::BackgroundRole); QBrush shouldBeRed = m_model->headerData(TAG_SERIALNUMBER, Qt::Horizontal, Qt::BackgroundRole);
PS: The test was done with Qt 5.11.2 on Linux.
-
wrote on 3 Nov 2018, 16:22 last edited by
-
Moderatorswrote on 3 Nov 2018, 16:51 last edited by kshegunov 11 Mar 2018, 16:51
QBrush brush = variant.value<QBrush>();
However you can inspect the data directly in the variant as well, as far as I can see in the watch.
-
@mzimmers: are you working on windows? https://bugreports.qt.io/browse/QTBUG-31804
-
@mzimmers: are you working on windows? https://bugreports.qt.io/browse/QTBUG-31804
wrote on 3 Nov 2018, 17:37 last edited by@Christian-Ehrlicher yes, I am, and that would seem to be the problem here. Plus, there's this:
Widget::Widget(DeviceModel *d, QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ... ui->tableView->horizontalHeader()->setBackgroundRole(QPalette::Window);
So, do I need to create a QStyle for the underlining, and set that on my header view?
-
@Christian-Ehrlicher yes, I am, and that would seem to be the problem here. Plus, there's this:
Widget::Widget(DeviceModel *d, QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ... ui->tableView->horizontalHeader()->setBackgroundRole(QPalette::Window);
So, do I need to create a QStyle for the underlining, and set that on my header view?
Moderatorswrote on 3 Nov 2018, 22:17 last edited by kshegunov 11 Mar 2018, 22:17@mzimmers said in formatting a QTableView header:
So, do I need to create a QStyle for the underlining, and set that on my header view?
I'd advise at least trying if that will fix the issue.
-
wrote on 5 Nov 2018, 17:09 last edited by
Do I need to derive a subclass from QStyle to do this?
-
@mzimmers said in formatting a QTableView header:
Do I need to derive a subclass from QStyle to do this?
Yes. But maybe try QProxyStyle instead, so you have less work to do.
-
wrote on 5 Nov 2018, 17:36 last edited by
I'm afraid that I'm going to have to temporarily abandon this thread. I just don't know enough about styles/hints/etc. and I don't have time to give it the attention it deserves.
Thanks for the assistance; I'll get back to this as soon as I can.
-
wrote on 7 Nov 2018, 19:53 last edited by
OK, I have a little spare time now. I've copied this code (from the page):
class MyProxyStyle : public QProxyStyle { public: int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const override { if (hint == QStyle::SH_UnderlineShortcut) return 0; return QProxyStyle::styleHint(hint, option, widget, returnData); } };
What would you suggest I use instead of SH_UnderlineShortcut to test whether my styling is taking effect? (Given the trouble we were having earlier.)
Thanks.
-
Hi,
How did you set your custom style ?
-
wrote on 7 Nov 2018, 20:46 last edited by
Hi SGaist - like this:
MyProxyStyle *mps = new MyProxyStyle; ui->tableView->setStyle(mps);
-
What if you set it application wide ?
-
wrote on 7 Nov 2018, 20:56 last edited by
I can try that. What I was asking for, though, was a style hint that would be readily apparent in my app. The one in the example might work perfectly, but I'd never see it without implementing any shortcuts (at least I think not).
-
wrote on 7 Nov 2018, 23:32 last edited by
For what it's worth, this line of code produces expected results:
ui->tableView->setStyleSheet("background-color: red");
But this one does not:
ui->tableView->horizontalHeader()->setStyleSheet("background-color: red");
So the problem seems to be in the header object, doesn't it?
-
I can try that. What I was asking for, though, was a style hint that would be readily apparent in my app. The one in the example might work perfectly, but I'd never see it without implementing any shortcuts (at least I think not).
Moderatorswrote on 8 Nov 2018, 07:33 last edited by kshegunov 11 Aug 2018, 07:34You don't need a style hint if you're trying to override the painting. You'd have to reimplement
QStyle::drawControl
and handle theQStyle::CE_Header
control. Something like this:class MyProxyStyle : public QProxyStyle { public: void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override { if (element != QStyle::CE_Header) { baseStyle()->drawControl(element, option, painter, widget); return; } // Paint here ... } };
It's been a long time since I last played with the styles, but I hope this is of help.
23/41