天天看点

一 QT之QTableView用QHeaderView添加横向表头

QTableView的表头用QHeaderView来添加,为了提高QTableView从sqlite数据库中提取数据的数据,通过设置QSqlQueryModel来添加。

1) 若是在表头不增加任何控件,而是直接增加个单独的表头,QTableView就提供了方便的添加横向表头的成员函数:void setHorizontalHeader (QHeaderView* pHeader);

由于项目需要,需要在第一列也就是序号显示列和其表头添加checkbox控件,以实现表数据全选的目的(说明:我这里纵向表头已隐藏)。

首先QHeaderView并没有添加checkbox这样的属性,看来需要自己在第一列的表头画出来此控件来。

首先我们来上代码,然后根据代码来说明怎么在第一列表头添加checkbox,为了程序能够跑起来,我将整个类的代码贴了上来,由于我也是第一次接触qt,在讲解不对或者写的不好的地方也请多多指教,谢谢!

 //表头类 viewHeader.h

class CViewHeader : public QHeaderView

{

    Q_OBJECT

public:

    CViewHeader(Qt::Orientation orientation, QWidget * parent = 0);

virtual ~CViewHeader(){}

protected:

    void paintSection( QPainter *painter, const QRect &rect, int logicalIndex ) const; //绘制checkbox

    void mousePressEvent(QMouseEvent *event);      //鼠标click事件

    void paintEvent( QPaintEvent* e );              //绘制checkbox事件

public slots:

    void SetHeaderBox( bool );      //设置表头checkbox状态

signals:

    void clickRow( bool );    //向操作表第一列所有项的checkbox发送信号

private:

    bool m_isOn;                //checkbox状态

    int m_iX;                   //横坐标

    int m_iY;                   //纵坐标

    bool m_isMousePress;         //是否按下

    int m_Style;                  //记录QStyle

};

 //viewHeader.cpp

CViewHeader::CViewHeader( Qt::Orientation orientation, QWidget * parent ) : QHeaderView(orientation, parent), m_iX(0), m_iY(3), m_Style(QStyle::State_Off),m_isOn(false),m_isMousePress(false)

{}

 //根据表头鼠标事件控制checkbox的状态,此事件在绘制之前触发

void CViewHeader::paintEvent( QPaintEvent* event )

{

    if( m_isMousePress )

    {

        m_isMousePress = false;

        if ( m_isOn ){

            m_Style = QStyle::State_On;

        }else{

            m_Style = QStyle::State_Off;

        }

    }

     QHeaderView::paintEvent( event );

}

//重载paintSection,此函数为const控制,函数内不允许对函数外部变量的修改

//绘制QStyleOptionButton的样式,这里选取*20大小

void CViewHeader::paintSection( QPainter *painter, const QRect &rect, int logicalIndex ) const

{

    painter->save();

    QHeaderView::paintSection(painter, rect, logicalIndex);

    painter->restore();

    if ( logicalIndex == 0 )

    {

        QStyleOptionButton RectOption;

        RectOption.rect = QRect( 0, 3, 20, 20 );

        if ( 0x00000020 == m_Style ){

            RectOption.state = QStyle::State_On;

        }else if( 0x00000008 == m_Style ){

            RectOption.state = QStyle::State_Off;

        }

         this->style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &RectOption, painter);

    }

 }

 //鼠标按下事件,为了屏蔽鼠标在第一列之外的事件,用visualIndexAt判断坐标是否在第一列范围之内

//另外为了屏蔽非表头的鼠标事件,用m_isMousePress做标记

void CViewHeader::mousePressEvent(QMouseEvent *event)

{

    m_iX = event->pos().x();

    m_iY = event->pos().y();

     int iSecondColume = sectionPosition( 1 );

    if( 0 == visualIndexAt( m_iX ) )

    {

        m_isMousePress = true;

        if ( m_isOn ){

          m_isOn = false;

          emit clickRow( false );

        }else{

          m_isOn = true;

          emit clickRow( true );

        }

        this->update( );

    }else

    {

        m_isOn = false;

        m_isMousePress = false;

    }

     QHeaderView::mousePressEvent(event);

}

 //这个是外部信号的触发达到改变checkbox状态的目的

void CViewHeader::SetHeaderBox( bool bBoxState )

{

     if ( !bBoxState ){

        m_Style = QStyle::State_Off;

     }

}

转载请注明:csdn http://blog.csdn.net/fanbiqi/article/details/40212875

继续阅读