How to set Checkbox in header of one column in QtreeView
-
Hi All
We need to set checkbox in header of one of the columns . I have following classclass MyHeader : public QHeaderView
{
public:
MyHeader(Qt::Orientation orientation, QWidget * parent = 0) : QHeaderView(orientation, parent)
{}protected:
void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
painter->save();
QHeaderView::paintSection(painter, rect, logicalIndex);
painter->restore();
if (logicalIndex == 0)
{
QStyleOptionButton option;
option.rect = QRect(10,10,10,10);
if (isOn)
option.state = QStyle::State_On;
else
option.state = QStyle::State_Off;
this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
}}
void mousePressEvent(QMouseEvent *event)
{
if (isOn)
isOn = false;
else
isOn = true;
this->update();
QHeaderView::mousePressEvent(event);
}
private:
bool isOn;
};class myView::QTreeView {
}
MyView::GQInstView(QWidget* dparent)
: QTreeView(dparent), {}
The tree View has three columns . How to set header for first column in treeView
-
-
- The tree View has three columns . How to set header for first column in treeView
Hi
I do not think you can replace for just column 1
You can set for treeview using
http://doc.qt.io/qt-5/qtreeview.html#setHeader
and that be for all columns. -
- set your custom header view to your items widget like @mrjj said
- instead of using "isOn" in the header class, query the model's headerData() method for the Qt::CheckStateRole
- in your model return the corresponding check state in headerData(). For column 1 return Qt::Checked, when you don't want to display a checkbox at all return an invalid QVariant
-
@raven-worx said:
odel's headerData() method for the Qt::CheckStateRole
in your model return the corresponding check state inhow to get model pointer
class MyHeader : public QHeaderView
{
public:
MyHeader(Qt::Orientation orientation, QWidget * parent = 0) : QHeaderView(orientation, parent)
{}protected:
void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
painter->save();
QHeaderView::paintSection(painter, rect, logicalIndex);
painter->restore();
if (logicalIndex == 0)
{
QStyleOptionButton option;
option.rect = QRect(10,10,10,10);
if (isOn)
option.state = QStyle::State_On;
else
option.state = QStyle::State_Off;
this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
}}
void mousePressEvent(QMouseEvent *event)
{
if (isOn)
isOn = false;
else
isOn = true;
this->update();
QHeaderView::mousePressEvent(event);
}
private:
bool isOn;
}; -
@Qt-Enthusiast said:
how to get model pointer
since QHeaderView derives from QAbstractItemView, you are doing it the same way you would do for table/trees/lists/... with the model() method
This model is the same as the item view widget has also set. -
#include <QApplication>
#include <QAbstractTableModel>
#include <QSortFilterProxyModel>
#include <QInputDialog>
#include <QTableView>
#include <QGridLayout>
#include <QPushButton>
#include <QDebug>
#include <QHeaderView>
#include <QStyle>
#include <QPainter>
#include <QMouseEvent>
#include <QTreeView>class MyHeader : public QHeaderView
{
public:
MyHeader(Qt::Orientation orientation, QWidget * parent = 0) : QHeaderView(orientation, parent)
{}protected:
void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const
{
painter->save();
QHeaderView::paintSection(painter, rect, logicalIndex);
painter->restore();
if (logicalIndex == 1 )
{
QStyleOptionButton option;
option.rect = QRect(10,10,10,10);
isOn = model()->headerData(1,Qt::Horizontal, Qt::CheckStateRole);
if (isOn)
option.state = QStyle::State_On;
else
option.state = QStyle::State_Off;
this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
}}
void mousePressEvent(QMouseEvent *event)
{if (isOn) isOn = false; else isOn = true; this->update(); QHeaderView::mousePressEvent(event);
}
private:
bool isOn;
};class Vehicle {
QString m_make, m_model, m_registrationNumber;
public:
Vehicle(const QString & make, const QString & model, const QString & registrationNumber = QString()) :
m_make(make), m_model(model), m_registrationNumber(registrationNumber) {}
QString make() const { return m_make; }
QString model() const { return m_model; }
QString registrationNumber() const { return m_registrationNumber; }
bool isRegistered() const { return !m_registrationNumber.isEmpty(); }
};class VehicleModel : public QAbstractTableModel {
QList<Vehicle> m_data;
public:
VehicleModel(QObject * parent = 0) : QAbstractTableModel(parent) {}
int rowCount(const QModelIndex &) const { return m_data.count(); }
int columnCount(const QModelIndex &) const { return 3; }
QVariant data(const QModelIndex &index, int role) const {
if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant();
const Vehicle & vehicle = m_data[index.row()];
switch (index.column()) {
case 0: return vehicle.make();
case 1: return vehicle.model();
case 2: return vehicle.registrationNumber();
default: return QVariant();
};
}
QVariant headerData(int section, Qt::Orientation orientation, int role) const {
if(role == Qt::CheckStateRole && orientation == Qt::Horizontal) {
switch (section) {
case 0: return Qt::Unchecked;
case 1: return Qt::Checked;
case 2: return Qt::Unchecked;
default: return QVariant();
}} if (orientation != Qt::Horizontal) return QVariant(); if (role != Qt::) return QVariant(); switch (section) { case 0: return "Make"; case 1: return "Model"; case 2: return "Reg.#"; default: return QVariant(); } } void append(const Vehicle & vehicle) { beginInsertRows(QModelIndex(), m_data.count(), m_data.count()); m_data.append(vehicle); endInsertRows(); }
};
class Widget : public QWidget {
VehicleModel m_model; QSortFilterProxyModel m_proxy; Q_SLOT void setFilter() { QInputDialog * dialog = new QInputDialog(this); dialog->setLabelText("Enter registration number fragment to filter on. Leave empty to clear filter."); dialog->setInputMode(QInputDialog::TextInput); dialog->open(&m_proxy, SLOT(setFilterFixedString(QString))); dialog->setAttribute(Qt::WA_DeleteOnClose); }
public:
Widget() {
QGridLayout * layout = new QGridLayout(this);
QTreeView view = new QTreeView;
MyHeader myH = new MyHeader(Qt::Horizontal);
view->setHeader(myH);
layout->addWidget(view, 0, 0, 1, 1);
QPushButton * btn = new QPushButton("Filter");
layout->addWidget(btn, 1, 0, 1, 1);
m_model.append(Vehicle("Volvo", "240", "SQL8941"));
m_model.append(Vehicle("Volvo", "850"));
m_model.append(Vehicle("Volvo", "940", "QRZ1321"));
m_model.append(Vehicle("Volvo", "960", "QRZ1628"));
view->setModel(&m_model);
}
};int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}could you guide me on the same how to have checkbox in above code as per your inputs
-
Have a look at this Qt blog https://blog.qt.io/blog/2012/09/28/qt-support-weekly-27-widgets-on-a-header/
-
@Qt-Enthusiast said:
could you guide me on the same how to have checkbox in above code as per your inputs
i just give you some snippets. I leave it to you to check the rest out, since it's pretty simple.
in the header:
void MyHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const { painter->save(); QHeaderView::paintSection(painter, rect, logicalIndex); painter->restore(); QVariant headerCheckState = model()->headerData(logicalIndex, Qt::Horizontal, Qt::CheckStateRole); if( headerCheckState .isValid() ) //only paint the checkbox if the model returned a valid qvariant { Qt::CheckState check = static_cast<Qt::CheckState>( headerCheckState.toInt() ); QStyleOptionButton option; option.rect = QRect(10,10,10,10); if ( checkState == Qt::Checked ) option.state = QStyle::State_On; else option.state = QStyle::State_Off; this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter); }
in the model:
QVariant MyModel::headerData(int section, Qt::Orientation orientation, int role ) const { if( orientation == Qt::Horizontal ) { switch( role ) { case Qt::CheckStateRole: { if( section == XXX ) // here you need to check which columns you want to display the checkbox { return QVariant::fromValue<int>(Qt::Checked); } } break; } } return QHeaderView::headerData(section,orientation,role); }
This way a checkbox is only displayed when you return a valid QVariant:
Invalid QVariant -> no checkbox
QVariant with Qt::CheckedState -> checked checkbox
QVariant with other value -> unchecked checkbox