如何在QtreeView的标题中实现复选框

时间:2016-05-31 10:11:13

标签: qt

我有以下使用QTreeView的代码。

#include <QApplication>
#include <QSplitter>
#include <QTreeView>
#include <QListView>
#include <QTableView>
#include <QStandardItemModel>

int main( int argc, char **argv ) {

   QApplication app( argc, argv );
   QTreeView *tree = new QTreeView();
   QListView *list = new QListView();
   QTableView *table = new QTableView();
   QSplitter splitter;
   splitter.addWidget( tree );
   splitter.addWidget( list );
   splitter.addWidget( table );
   QStandardItemModel model( 5, 2 );

   for( int r=0; r<5; r++ ) 
      for( int c=0; c<2; c++)  {
          QStandardItem *item = new QStandardItem( QString("Row:%0, Column:%1").arg(r).arg(c) );
         if( c == 0 )
         for( int i=0; i<3; i++ ) {
             QStandardItem *child = new QStandardItem( QString("Item %0").arg(i) );
             child->setEditable( false );
             item->appendRow( child );
          }
          model.setItem(r, c, item);
      }

    model.setHorizontalHeaderItem( 0, new QStandardItem( "Foo" ) );
    model.setHorizontalHeaderItem( 1, new QStandardItem( "Bar-Baz" ) );
    tree->setModel( &model );
    list->setModel( &model );
    table->setModel( &model );
    list->setSelectionModel( tree->selectionModel() );
    table->setSelectionModel( tree->selectionModel() );
    table->setSelectionBehavior( QAbstractItemView::SelectRows );
    table->setSelectionMode( QAbstractItemView::SingleSelection );
    splitter.show();
    return app.exec();
 }

我想在QTreeView的标题中实现一个复选框。当我们点击复选框时,应该调用一个插槽,当我们取消选中该复选框时,应该调用另一个插槽。如果有人可以指导我使用相同的

,这将会很有帮助

1 个答案:

答案 0 :(得分:3)

您可以根据本文制作自己的解决方案:https://wiki.qt.io/Qt_project_org_faq#How_can_I_insert_a_checkbox_into_the_header_of_my_view.3F。您必须为QHeaderView重新实现QTreeView

简单示例:

#include <QApplication>
#include <QSplitter>
#include <QTreeView>
#include <QListView>
#include <QTableView>
#include <QStandardItemModel>
#include <QHeaderView>
#include <QPainter>
#include <QMessageBox>

class MyHeader : public QHeaderView
{
  Q_OBJECT

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;
    emit signalCheckedChanged(isOn);
    this->update();
    QHeaderView::mousePressEvent(event);
  }
private:
  bool isOn;

signals:
  void signalCheckedChanged(bool);
};

class MySplitter: public QSplitter
{
    Q_OBJECT
public:
    MySplitter(QWidget * parent = 0)
        :QSplitter(parent)
    {}
    ~MySplitter(){}
public slots:
    void slotTreeViewHeaderCheckedChanged(bool checked)
    {
        // your code. For example, QMessageBox
        QMessageBox::information(this, "!", checked ? "checked" : "unchecked");
    }
};

int main( int argc, char **argv ) {

   QApplication app( argc, argv );
   MySplitter splitter;
   QTreeView *tree = new QTreeView(&splitter);
   QListView *list = new QListView(&splitter);
   QTableView *table = new QTableView(&splitter);
   splitter.addWidget( tree );
   splitter.addWidget( list );
   splitter.addWidget( table );
   QStandardItemModel model( 5, 2 );

   for( int r=0; r<5; r++ )
      for( int c=0; c<2; c++)  {
          QStandardItem *item = new QStandardItem( QString("Row:%0, Column:%1").arg(r).arg(c) );
         if( c == 0 )
         for( int i=0; i<3; i++ ) {
             QStandardItem *child = new QStandardItem( QString("Item %0").arg(i) );
             child->setEditable( false );
             item->appendRow( child );
          }
          model.setItem(r, c, item);
      }

    model.setHorizontalHeaderItem( 0, new QStandardItem( "Foo" ) );
    model.setHorizontalHeaderItem( 1, new QStandardItem( "Bar-Baz" ) );
    tree->setModel( &model );
    list->setModel( &model );
    table->setModel( &model );
    list->setSelectionModel( tree->selectionModel() );
    table->setSelectionModel( tree->selectionModel() );
    table->setSelectionBehavior( QAbstractItemView::SelectRows );
    table->setSelectionMode( QAbstractItemView::SingleSelection );

    MyHeader* myHeader = new MyHeader(Qt::Horizontal, tree);
    tree->setHeader(myHeader);

    QObject::connect(myHeader, &MyHeader::signalCheckedChanged,
                     &splitter, &MySplitter::slotTreeViewHeaderCheckedChanged);

    splitter.show();
    return app.exec();
 }

#include "main.moc"