0

我正在使用 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 进行实际绘图,那么继承这里有什么好处?

我想改变它的绘图方式。

4

1 回答 1

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 源代码。如果您正在实现自己的绘画功能,则不必使用此宏。

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

于 2011-07-11T03:53:33.583 回答