通过继承QTreeView创建类

时间:2011-07-11 03:06:42

标签: qt inheritance qtreeview

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

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

首先,我想要的是创建一个层次树视图,它允许我查看包含其他类别的类别,列越往右,它们就越具体,直到达到最具体的类别。度量标准显示在包含最具体列的行上。包含每个通用列的视图行将是粗体,并包含由模型(或视图?)计算的每个度量的摘要。根据最具体的列,指标将位于每行的模型中。

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

国家|省省|县教区|市城|人口| PerCapitaIncome | WalMarts

所以我的观点看起来与此相似:

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的简单类,其中包含一个只调用QTreeView方法的通用ctor和dtor。至于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来进行实际的绘制,那么继承这里有什么好处呢?

我想改变它的绘画方式。

1 个答案:

答案 0 :(得分: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,你可能需要文档中的很多内容。