【问题标题】:Create class by inheriting from QTreeView通过继承 QTreeView 创建类
【发布时间】:2011-07-11 03:06:41
【问题描述】:

我正在使用 Qt 开始一个项目。我正在尝试两种方法来让 View 执行以下一些操作。本题涉及到从QTreeView继承的方式。

我喜欢 QTreeView 的功能。我只是想要一些附加功能。

首先,我想要创建一个层次结构树视图,让我可以查看包含其他类别的类别,列越靠右越具体,直到它变得最具体。指标显示在包含最具体列的行上。包含每个通用列的视图行将是粗体并包含每个指标的摘要,由模型(或视图?)计算。根据最具体的列,指标将位于模型中的每一行。

例如,考虑具有以下数据的模型(最后 3 列包含数字):

国家|省-州|县-教区|城镇|人口|人均收入|沃尔玛

所以我的观点应该是这样的:

Country Province-State County-Parish City-Town Population PerCapitaIncome Walmarts
+ USA                                           250000000           42000     2354
        + Alabama                                 9000000           23000      153
                       + Barbour                    15324           19032        1
                                     Eufaula         6520           23000        1
        + Tennessee                              14000000           29000      299
                       + Hamilton                   70000           41000        4
                                     East Ridge     23000           32000        2

其次,我需要它与 QSqlTableModel 一起工作。我以前看过它显示模型,但它没有任何方法可以按层次结构创建行,类似于上面。那将是我的第二次修改。

第三个原因是粗体标题只有在您通过以下方式打开排序时才可以选择:

 view->setSortingEnabled(true);

打开排序时,粗体标题仅适用于较高的行,然后在较低的行上关闭。我想修复那个错误。

QTreeView::drawRow 虚拟方法看起来是我完成第一个挑战(也许是第三个挑战)所需的全部。处理 QSqlTableModel 的第二个挑战,我不太确定。

无论如何,我构建了一个从 QTreeView 继承的简单类,它带有一个通用 ctor 和 dtor,它只调用 QTreeView 方法。然而,对于 drawRow,我遇到了以下问题。 QTreeView::drawRow 函数的开头是这样的:

QTreeView::drawRow(
    QPainter *painter,
    const QStyleOptionViewItem &option,
    const QModelIndex &index) const {

  Q_D(const QTreeView);
  QStyleOptionViewItemV4 opt = option;
  const QPoint offset = d->scrollDelayOffset;
  const int y = option.rect.y() + offset.y();
  const QModelIndex parent = index.parent();
  const QHeaderView *header = d->header;
  const QModelIndex current = currentIndex();
  const QModelIndex hover = d->hover;
  const bool reverse = isRightToLeft();
  const QStyle::State state = opt.state;
  const bool spanning = d->spanning;
  const int left = (spanning ? header->visualIndex(0) : d->leftAndRight.first);
  const int right = (spanning ? header->visualIndex(0) : d->leftAndRight.second);
  ...

该函数依赖于 Q_D(const QTreeView) 成功运行并返回“d”,这是 QTreeViewPrivate 类的一个实例,其中包含与布局相关的重要信息和函数的其余部分。由于我继承了我的 CustomTreeView 类,如果我要在 CustomTreeView::drawRow() 中运行 Q_D(const QTreeView),则必须首先定义和实例化 CustomTreeViewPrivate。

创建这个私有类真的有必要继承和做出重大改变吗?如果我能做的只是一些敷衍的过程,然后调用QTreeView::drawRow进行实际绘图,那么继承这里有什么好处?

我想改变它的绘图方式。

【问题讨论】:

    标签: qt inheritance qtreeview


    【解决方案1】:

    我会尽量涵盖您的问题。贯穿所有问题的最重要的一点是,您尝试完成的大部分工作都应该通过模型而不是视图来完成(例如将某些条目以粗体显示)。因此,您将不得不制作自己的模型。您可以继承 QSqlTableModel 并根据需要更改内容。例如,如果你想加粗某些项目,在数据模型中,你可以写

    QVariant MyModel::data(const QModelIndex & index, int role) const
    {
        QVariant result = QSqlTableModel::data(index, role);
        // add your own qualifications to the following if statement, checking the row
        // and such
        if(role == Qt::FontRole) {
            QFont font = result.value<QFont>();
            font.setBold(true);
            return font;
        }
        return result;
    }
    

    你写的最后一件事是关于 Q_D。这仅用于 Qt 源代码。如果您要实现自己的绘画功能,则不必使用此宏。

    我会大量阅读models,您可能需要很多文档中的内容。

    【讨论】:

    • 是的,我想我也需要一个自定义模型类,继承自其中一种 SqlModel 类型。几天前我得到了一个工作示例,每个“层次结构”级别使用一个循环和一个 QSqlQueryModel,例如“select Country”、“”、“”、“”、sum(Population)、sum(PerCapita)、sum(Walmarts) ”。我会将结果添加到 QList,然后添加到 QStandardItemModel 中的一行。我会在该循环中运行另一个查询,例如“select”、“Province-State”、“”、“”、sum(Population)、sum(PerCapita)、sum(Walmarts)”等。然后我创建了一个 QTreeView并将 QStandardItemModel 附加到那个。
    • 上述方法可行,但我没有一个好的方法可以将视图的更改推送回数据库表。因此,我正在考虑继承 QViewTree 以使其更好地与 QSqlTableModel 一起工作(目前,它不适用于从 QAbstractTableModel link 继承的类。感谢您的建议。我想我可以使用原始设置完成一些事情一个 QSqlTableModel 来做更新。我会考虑这个。我仍然想知道为什么我不能让 QTreeView 绘制任何不同的东西。
    猜你喜欢
    • 2018-05-10
    • 1970-01-01
    • 2021-02-21
    • 2011-02-21
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    • 2012-06-26
    • 2016-08-19
    相关资源
    最近更新 更多