表格表头中的QCheckBox单击勾选时无效的问题解决

表格表头中的QCheckBox单击勾选时无效的问题解决

问题:表格表头设置了checkbox,正常点击应该代表全选。该CheckBox应该变成勾选状态,其下方每一行的CheckBox也应一并勾选成功。现在问题是点击表头的CheckBox无效,CheckBox的状态并没有改变。

解决思路:代码的逻辑是写了一个CHeaderView类继承自QHeaderView类,在该类中重写了mouseReleaseEvent(QMouseEvent*)函数,函数中有一处if语句中调用sectionsClickable()函数判断表头是否是可点击的。通过打断点的方式发现这个函数返回了false,导致程序没有进入到if语句中去重画CheckBox。在外面实例化CHeaderView的地方加上setSectionsClickable(true),但是仍然无效。此时怀疑是代码某些地方调用了setSectionsClickable(false),把表头section可点击状态设置为了false,导致获取到的状态是false。
在代码中全局搜索setSectionsClickable函数,发现并没有地方设置了false。转换思路,怀疑是其他控件重写mouseReleaseEvent(QMouseEvent*)函数导致了某些异常。该表格是用一个CTableView类实现,最上层的父类是QTreeView,走读代码发现没有地方重写mouseReleaseEvent会影响CHeaderView中的该函数。因此必须再次转换思路,继续排查。
注意到其他地方也有类似的表格,只是表格表头和展示内容不同,第一列均是CheckBox,勾选表头的CheckBox,下方每一行均全选,而另外一处的这个表格CheckBox是正常的,勾选时sectionsClickable()返回true,也调用了setSectionsClickable(true)。开始比较两处使用时有什么差异。注意到两个控件都设置了点击表头不能进行排序。但是功能正确的表格是先调用setSortingEnabled(false),后调用setSectionsClickable(true),而此处是反过来调用的。
思考下QT如何实现点击表头不进行排序功能,推测可能会把表头的可点击状态改为false,这样点击时不生效,自然就不会继续排序。为了验证猜想,查看QT源码。查看源码发现QTreeView中的setSortingEnabled函数中会调用其header的setSectionsClickable函数,将其状态置为setSortingEnabled的参数,因此应先设置setSortingEnabled,再调用header的setSectionsClickable把状态设置为true,这样mouseReleaseEvent(QMouseEvent*)函数中的sectionsClickable()返回true,勾选CheckBox生效了,问题解决。

涉及的源码如下:

void QTreeView::setSortingEnabled(bool enable)
{
    Q_D(QTreeView);
    header()->setSortIndicatorShown(enable);
    header()->setSectionsClickable(enable);
    if (enable) {
        //sortByColumn has to be called before we connect or set the sortingEnabled flag
        // because otherwise it will not call sort on the model.
        sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
        connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
                this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection);
    } else {
        disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
                   this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)));
    }
    d->sortingEnabled = enable;
}

解决方法:设置点击表头不能排序和点击表头可改变CheckBox状态时,应先设置setSortingEnabled,再调用header的setSectionsClickable,避免setSortingEnabled的false把setSectionsClickable设置的true给覆盖。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值