setHorizo​​ntalHeader()之后,QTableView排序失败 [英] QTableView sorting fails after setHorizontalHeader()

查看:122
本文介绍了setHorizo​​ntalHeader()之后,QTableView排序失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过setHorizontalHeader()设置了新的QHeaderView实例后,PySide QTableView遇到了一个奇怪的问题.具体来说,该视图的排序功能似乎已损坏/无法再调用.

I am encountering a strange problem with PySide QTableViews after I have set a new QHeaderView instance via setHorizontalHeader(). Specifically it seems that the sorting ability of the view is broken/cannot be invoked anymore.

  • 设置新的标题视图后,为什么排序会中断?
  • 为什么通过setHorizontalHeader()设置新头后,仅在头视图实例 上的Monkeypatching方法起作用 ? (请参见演示代码中的wrap_size_hint().)
  • 记录表视图的子级时,为什么总是2个QHeaderView实例?
  • QHeaderView上的initialize()方法实际上在做什么?它们在任何方面都可以有用吗? 文档不是'很有帮助.
  • Why is the sorting broken after a new header view is set?
  • Why does monkeypatching methods on the header view instance only work after a setting a new header via setHorizontalHeader()? (See wrap_size_hint() in the demo code.)
  • When logging the children of the table view, why are the always 2 QHeaderView instances?
  • What are the initialize() methods on the QHeaderView actually doing? Could they be useful here in any way? The docs aren't quite that helpfull.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function, division

import logging
import sys

from PySide import QtCore
from PySide import QtGui


# configure logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)


def wrap_size_hint(func):
    """Monkeypatch virtual method to increase sizeHint.

    Notes:
        Strangely this does not work when when no custom header is set on the
        table view.
    """

    def wrapped(*args, **kwargs):
        """Just extend sizeHint to increase height."""
        size = func(*args, **kwargs)  # QSize
        height_increase = 60
        height = size.height() + height_increase
        size.setHeight(height)
        return size

    return wrapped


class CustomHeaderView(QtGui.QHeaderView):
    """CustomHeaderView"""


class TestWidget(QtGui.QWidget):

    def __init__(self, use_custom_headerview=True, *args, **kwargs):
        super(TestWidget, self).__init__(*args, **kwargs)

        self.logger = logging.getLogger(type(self).__name__)

        QtGui.QVBoxLayout(self)

        self.setup_mvc(use_custom_headerview)
        self.update_model()
        self.log_children(self.view)

    def setup_mvc(self, use_custom_headerview):
        layout = self.layout()

        # model
        header_labels = "One Two Three Four Five".split()
        self.model = QtGui.QStandardItemModel()
        self.model.setHorizontalHeaderLabels(header_labels)

        # proxymodel
        self.proxymodel = QtGui.QSortFilterProxyModel()
        self.proxymodel.setDynamicSortFilter(True)
        self.proxymodel.setSourceModel(self.model)

        # view
        self.view = QtGui.QTableView()
        if (use_custom_headerview is True):
            self.view.setHorizontalHeader(CustomHeaderView(QtCore.Qt.Horizontal))

        self.view.setSortingEnabled(True)
        self.view.setModel(self.proxymodel)

        # monkeypatch sizeHint to increase size
        headerview = self.view.horizontalHeader()
        headerview.sizeHint = wrap_size_hint(headerview.sizeHint)

        layout.addWidget(self.view)

    def update_model(self):

        for row in range(50):
            items = []

            for column in range(self.model.columnCount()):
                text = "{0} {1}".format(row, column)
                item = QtGui.QStandardItem()
                item.setEditable(True)
                item.setData(text, QtCore.Qt.DisplayRole)
                items.append(item)

            self.model.appendRow(items)

    def log_children(self, widget, tab=-1):
        tab += 1
        msg = "{0}{0}: {1}".format("--"*tab, type(widget).__name__, widget)
        self.logger.info(msg)
        for child in widget.children():
            self.log_children(child, tab)


if (__name__ == "__main__"):

    app = QtGui.QApplication(sys.argv)

    # widget_sorting_fails
    widget_sorting_fails = TestWidget(use_custom_headerview=True)
    widget_sorting_fails.setWindowTitle("Custom headerview")
    widget_sorting_fails.show()

    logger.info("-"*100)

    # widget_sorting_succeeds
    widget_sorting_succeeds = TestWidget(use_custom_headerview=False)
    widget_sorting_succeeds.setWindowTitle("No custom headerview")
    widget_sorting_succeeds.show()

    # start event loop
    sys.exit(app.exec_())

推荐答案

好,发现setClickable(True)可以解决问题.默认情况下,似乎在QTableView标头视图上处于启用状态,但在手动创建的实例上则未处于打开状态.

Ok, found out that setClickable(True) will do the trick. Seems to be on by default on QTableView header views but not on instances created manually.

这篇关于setHorizo​​ntalHeader()之后,QTableView排序失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆