不能从 `QSortFilterProxyModel` 派生

Posted

技术标签:

【中文标题】不能从 `QSortFilterProxyModel` 派生【英文标题】:Cannot derive from `QSortFilterProxyModel` 【发布时间】:2014-02-20 17:32:58 【问题描述】:

我正在尝试使用自定义QSortFilterProxyModel

这是我的标题:

#include <QSortFilterProxyModel>

class QSortFilterProxyModel_NumbersLast : public QSortFilterProxyModel


    Q_OBJECT

    public:

        QSortFilterProxyModel_NumbersLast(QObject * parent = nullptr);

        bool lessThan(const QModelIndex &left, const QModelIndex &right) const;

;

这是来自源文件的构造函数:

QSortFilterProxyModel_NumbersLast::QSortFilterProxyModel_NumbersLast(QObject * parent)
    : QSortFilterProxyModel(parent)


(另外,我正确地 - 我认为 - 称为 Q_DECLARE_METATYPE(QSortFilterProxyModel_NumbersLast) qRegisterMetaType<QSortFilterProxyModel_NumbersLast>("QSortFilterProxyModel_NumbersLast"); 。)

很遗憾,我从编译器收到以下错误:

错误 C2248:“QSortFilterProxyModel::QSortFilterProxyModel”:不能 访问在类“QSortFilterProxyModel”中声明的私有成员

...我确实注意到基类的构造函数QSortFilterProxyModel::QSortFilterProxyModel 被声明为public

// (From *qsortfilterproxymodel.h*, in the Qt core)
public:
    explicit QSortFilterProxyModel(QObject *parent = 0);

我的问题:为什么我会收到错误'QSortFilterProxyModel::QSortFilterProxyModel' : cannot access private member我该怎么做才能解决这个问题?


注意:

从其他问题,例如this、this 和this,我看到我可能会通过复制某处 - QObjects 不允许这样做。

但是,我的QSortFilterProxyModel_NumbersLast 的唯一用途如下:

QStandardItemModel * model = new QStandardItemModel(ui->listView_dmu_members);
QSortFilterProxyModel_NumbersLast *proxyModel = new QSortFilterProxyModel_NumbersLast(ui->listView_dmu_members);
proxyModel->setSourceModel(model);
ui->listView_dmu_members->setModel(model);

...我认为这不会触发副本。


注2:

根据@KubaOber 的 cmets:

我已删除 Q_DECLARE_METATYPE(QSortFilterProxyModel_NumbersLast) qRegisterMetaType<QSortFilterProxyModel_NumbersLast>("QSortFilterProxyModel_NumbersLast"); 注册。我现在收到的错误是:

类型未注册,请使用 Q_DECLARE_METATYPE 宏 让 Qt 的元对象系统知道它

我不相信我在复制 QSortFilterProxyModel_NumbersLast 实例。因此,我不明白为什么会触发此错误。

(请注意,最初,我没有注册了QSortFilterProxyModel_NumbersLast 类。只是由于上述错误,我才注册了该类。但回想起来,我很清楚, QObject-派生类不能注册,因为不能复制。)

【问题讨论】:

Kuba - 建议 我可能在代码的其他地方做的事情是一回事。告诉我我必须做什么是另一回事。我相当明确地告诉您,我更新了我的问题以确认我没有在此实例上明确调用信号/插槽连接。此外,这是一个 compile-time 错误 - 我如何在调试器中单步执行代码? 【参考方案1】:

Q_DECLARE_METATYPE 需要访问 复制构造函数,并且在所有 QObject 派生类中删除 (C++11) 或不可访问 (C++98)。这就是编译器抱怨的构造函数。解决方法是不声明代理过滤器模型元类型。

以下内容适用于我在 Qt 4.5.8 和 5.2.1 下,跨主要桌面平台。

#include <QApplication>
#include <QSortFilterProxyModel>
#include <QListView>
#include <QStandardItemModel>

class QSortFilterProxyModel_NumbersLast : public QSortFilterProxyModel

   Q_OBJECT
public:
   QSortFilterProxyModel_NumbersLast(QObject * parent = nullptr) :
      QSortFilterProxyModel(parent) 
   bool lessThan(const QModelIndex &, const QModelIndex &) const 
      return false;
   
;

int main(int argc, char *argv[])

   QApplication app(argc, argv);
   QStandardItemModel * model = new QStandardItemModel(&app);
   QSortFilterProxyModel_NumbersLast *proxyModel = new QSortFilterProxyModel_NumbersLast(&app);
   proxyModel->setSourceModel(model);
   QListView view;
   view.setModel(model);
   view.show();
   model->appendRow(new QStandardItem("Foo"));
   model->appendRow(new QStandardItem("Bar"));
   model->appendRow(new QStandardItem("Baz"));
   return app.exec();


#include "main.moc"

在 Qt 5 中,您看到的错误消息来自 qMetaTypeId 方法。它是一个静态断言,因此您可能会看到编译时错误。从qRegisterMetaType 和其他一些地方调用此方法,主要与QObjectQVariant 中的模板连接方法有关。

【讨论】:

在注册类型之前,我收到了一个我没有收到的错误。我把这里的注册去掉,看看是否重现错误。 我不是connect使用代理模型的信号/槽。至少没有明确地在任何地方。 @DanNissenbaum 这是您总结未提供重现该问题的单一文件、自包含示例而使自己陷入困境的问题之一。你会在几分钟内确切地知道出了什么问题。除非您提供这样的示例,否则我将投票以将其关闭为不可复制。测试用例是你的工作,没有它,问题就无法挽救。 @DanNissenbaum 这是问题的要求:您所显示的内容中没有任何内容会触发错误。我坚持认为您确实是在踢自己的脚-当您拒绝提供可重现的测试用例时,没有人可以提供帮助。并不是我不知道错误在哪里——它不在这里,所以我需要想象一个你需要触发它的构造。我做bug的想象力有限,抱歉。我唯一想到的就是连接。事实并非如此。一旦你有了一个最小的测试用例,问题出在哪里就很明显了。帮助我们帮助您。 @DanNissenbaum 并非所有问题都需要一个独立的最小案例。这个可以。 确实如此。您所期望的是,这里的每个人都能够想出您在未显示的代码中犯了什么错误。我添加了一个有效的示例。拿它,改变它,让它坏了,然后你就有了一个有效的问题。否则,我们在追松鼠,你在浪费时间。是的,拒绝是一个强有力的词,而这正是你正在做的事情:争论而不是处理最小的、可重现的测试用例。你确实拒绝我们帮助你。

以上是关于不能从 `QSortFilterProxyModel` 派生的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能从数组中得到正确的日期?

为啥我不能从 FragmentPagerAdapter 分离片段?

为啥类不能从 decltype 的结果继承?

为啥我不能从内部调用一个类的 start 函数?

为啥我的 .pushViewController 不能快速从 didSelectItemAt 工作

不能从 `QSortFilterProxyModel` 派生