zoukankan      html  css  js  c++  java
  • 列表标题栏添加CheckBox(自定义HanderView的时候实现)

         前段时间项目上的要求,要实现一个列表(见下图1)。类似网页上的列表,可以通过选中标题栏的复选框,实现全选或者全不选的功能。但是看了很久,都没看到Qt哪个方法可以实现在标题栏添加控件。

          

                                                图1

    要实现这样的效果,也许我们首先想到的,就是直接生成一个CheckBox,用setGeometry()设置它的位置就可以了。当然这样是可以的,也是最简单的。但是有个问题:这样做,CheckBox就固定死了,而且没有跟标题栏连城一体,不会随着标题栏一起移动。结果如下图2

    显然,这样的效果有点不爽。

    后面想到了一种比较好的办法,就是自定义一个heander。通过setHeader()设置给列表。下面是我的部分实现代码

    [cpp] view plain copy
     
    1. class MyCheckBox:public QCheckBox  
    2. {  
    3.     Q_OBJECT  
    4. public:  
    5.     MyCheckBox(QWidget *parent /*= NULL*/):QCheckBox(parent)  
    6.     {  
    7.   
    8.     }  
    9.     ~MyCheckBox(){}  
    10.   
    11. protected:  
    12.   
    13.     void mouseMoveEvent(QMouseEvent *e)  
    14.     {  
    [cpp] view plain copy
     
    1.         //HeaderView::mouseMoveEvent(e);  
    2.         QRect boxRect = this->rect();  
    3.         QPoint pos = e->pos();  
    4.         if (boxRect.contains(pos))  
    5.         {  
    6.             setCursor(Qt::ArrowCursor);  
    7.         }  
    8.     }  
    9. private:  
    10.   
    11. };  
    12.   
    13.   
    14. class HanderView :public QHeaderView   
    15. {  
    16.   
    17.     Q_OBJECT  
    18. public:  
    19.     HanderView( Qt::Orientation orientation,QWidget *parent /*= NULL*/):QHeaderView(orientation,parent)  
    20.     {  
    21.         m_pCheckBox = new MyCheckBox(this);  
    22.         hasPaint = false;  
    23.     }  
    24.     ~HanderView()  
    25.     {  
    26.   
    27.     }  
    28. private slots:  
    29. protected:  
    30.   
    31.   
    32.     void resizeEvent(QResizeEvent *event)  
    33.     {  
    34.         int leftPos = this->sectionViewportPosition(0);  
    35.         m_pCheckBox->setGeometry(leftPos + 5,0,50,this->height());  
    36.         int sectionMinSize = 50;  
    37.         this->setMinimumSectionSize(sectionMinSize + sectionSizeFromContents(0).width());  
    38.         this->setDefaultSectionSize(sectionMinSize + sectionSizeFromContents(0).width());  
    39.     }  
    40.   
    41.     void paintEvent(QPaintEvent *e)  
    42.     {  
    43.         QHeaderView::paintEvent(e);  
    44.         int leftPos = this->sectionViewportPosition(0);  
    45.         m_pCheckBox->setGeometry(leftPos + 5,0,50,this->height());  
    46.     }  
    47. private:  
    48.     MyCheckBox   *m_pCheckBox;  
    49.     bool hasPaint;  
    50. };  
    [cpp] view plain copy
     
    1. class MyTreeWidget:public QTreeWidget  
    2. {  
    3.     Q_OBJECT  
    4. public:  
    5.     MyTreeWidget(QWidget *parent = NULL);  
    6.     ~MyTreeWidget();  
    7.   
    8. protected:  
    9.   
    10. private:  
    11.     HanderView   *m_pHeader;  
    12. };  
    [cpp] view plain copy
     
    1. MyTreeWidget::MyTreeWidget(QWidget *parent /* = NULL */):QTreeWidget(parent)  
    2. {  
    3.     m_pHeader = new HanderView(Qt::Horizontal,parent);  
    4.     this->setHeader(m_pHeader);  
    5.     QStringList list ;  
    6.     list<<"文件名"<<"文件大小"<<"文件类型"<<"创建日期";  
    7.     this->setHeaderLabels(list);  
    8.     header()->setDefaultAlignment(Qt::AlignCenter);  
    9. }  


    1、这里是为了保证鼠标在标题栏上是箭头状,因为Box靠近分割线,不这么做的话,鼠标移动到Box上面的时候也可能是Qt::SplitHCursor。这样对用户感觉有点不爽。大家可以试试注释这些代码看看就知道了

    [cpp] view plain copy
     
    1. void mouseMoveEvent(QMouseEvent *e)    
    2. {  
    [cpp] view plain copy
     
    1. //HeaderView::mouseMoveEvent(e);  
    2. QRect boxRect = this->rect();  
    3. QPoint pos = e->pos();  
    4. if (boxRect.contains(pos))  
    5. {  
    6.     setCursor(Qt::ArrowCursor);  
    7. }  

    2、

    [cpp] view plain copy
     
    1. int leftPos = this->sectionViewportPosition(0);  
    2. m_pCheckBox->setGeometry(leftPos + 5,0,50,this->height());  
    3. int sectionMinSize = 50;  
    4. this->setMinimumSectionSize(sectionMinSize + sectionSizeFromContents(0).width());  
    5. this->setDefaultSectionSize(sectionMinSize + sectionSizeFromContents(0).width());  

    设置列的最小宽度。

    [cpp] view plain copy
     
    1. sectionSizeFromContents(0).width()这个可以根据标题栏的字符的长度调整列的宽度。  

    3、

    [cpp] view plain copy
     
    1. int leftPos = this->sectionViewportPosition(0);  
    2. m_pCheckBox->setGeometry(leftPos + 5,0,50,this->height());  

    这里保证移动滚动条的时候,Box会跟着标题栏动。

    效果如图3,图4

                          图3                                                                                              图4

    4、我们也可以把Box放在其他列,改一下index就可以了

    [cpp] view plain copy
     
    1. int leftPos = this->sectionViewportPosition(1);  
    2. m_pCheckBox->setGeometry(leftPos + 5,0,50,this->height());  
    3. int sectionMinSize = 50;  
    4. this->setMinimumSectionSize(sectionMinSize + sectionSizeFromContents(1).width());  
    5. this->setDefaultSectionSize(sectionMinSize + sectionSizeFromContents(1).width());  
    [cpp] view plain copy
     
    1. int leftPos = this->sectionViewportPosition(1);  
    2. m_pCheckBox->setGeometry(leftPos + 5,0,50,this->height());  

    结果如图5,图6

                                                        图5                                                                                                                                        图6

    http://blog.csdn.net/hai200501019/article/details/9150691

  • 相关阅读:
    最近很火的GAN应用
    pose项目里我遇到的问题
    pose的初体验
    Ubuntu 移动硬盘不能用
    深度学习中参数量与计算量的理解
    GAN的流程-cyclegan为例
    The version of SOS does not match the version of CLR you are debugging
    mnist 手写数字识别
    计算模型-图、数据模型-张量、运算模型-会话
    tensorflow环境安装
  • 原文地址:https://www.cnblogs.com/findumars/p/5175989.html
Copyright © 2011-2022 走看看