2015-08-15 40 views
1

我想在最后添加一列。 我想将QPushButtons添加到该列。 但是,我不知道该怎么做。 关注点如下。如何覆盖QSqlRelationalTableModel?

  1. 当我重写的数据(常量QModelIndex &指数,诠释角色),我不得不重写所有的数据,是可以避免的?`

  2. ,当我回到新QPushButton为的QVariant,它抛出一个错误信息。我不知道如何解决。 C:\Qt\5.4\mingw491_32\include\QtCore\qvariant.h:462: error: 'QVariant::QVariant(void*)' is private inline QVariant(void *) Q_DECL_EQ_DELETE;

    QVariant ActionSqlRelationModel::data(const QModelIndex &index, int role) const 
    { 
        if (role == Qt::DisplayRole) 
        { 
         return new QPushButton; 
        } 
        return QVariant(); 
    } 
    

我尝试使用QIdentityProxyModel但它出现的错误消息。 我只是试图重写columncount。

+0

看来我应该使用QAbstructTableModel和QSqlQuery做我自己的... – Woody

回答

1

当我重写数据(常量QModelIndex &指数,诠释角色),我不得不重写所有的数据,是可以避免的?

是的。您需要转发给基类的实现:

void MyModel : public BaseModel { 
public: 
    QVariant data(const QModelIndex & index, int role) const Q_DECL_OVERRIDE { 
    if (index.column() == BaseModel::columnCount()) { 
     // extra column 
     return "MyData"; 
    } 
    return BaseModel::data(index, role); 
    } 
    int columnCount() const Q_DECL_OVERRIDE { 
    return BaseModel::columnCount() + 1; 
    } 
    ... 
}; 

你也可以使用一个QIdentitityProxyModel而非推导示范基地,并覆盖其方法,而不是 - 这样你可以轻松地添加额外的列不管是什么型号用于保留其余的数据。

具体做法是:

void MyProxy : public QIdentityProxyModel { 
public: 
    QVariant data(const QModelIndex & index, int role) const Q_DECL_OVERRIDE { 
    if (index.column() == BaseModel::columnCount()) { 
     // extra column 
     return "MyData"; 
    } 
    return QIdentityProxyModel::data(index, role); 
    } 
    int columnCount() const Q_DECL_OVERRIDE { 
    return BaseModel::columnCount() + 1; 
    } 
    MyProxy(QObject * parent = 0) : QIdentityProxyModel(parent) {} 
}; 

,那么你会在视图代替原有的模型中使用。为了让代理知道它应该作为代理的模型,您可以使用setSourceModel方法。例如:

int main(int argc, char ** argv) { 
    QApplication app(argc, argv); 
    QTableView view; 
    QSqlRelationalTableModel model; 
    MyProxy proxy; 
    ... 
    proxy.setSourceModel(&model); 
    view.setModel(&proxy); 
    view.show(); 
    return app.exec(); 
} 

当我回到新QPushButton为的QVariant,它抛出一个错误消息。

首先,从data方法返回一个小部件,即使您设法做到这一点,也不会被视图处理。视图不会使用这样的小部件 - 他们会忽略它。所以它不会工作。我在下面展示了一个人如何去做,但它只是为了满足你的好奇心 - 这是一个完全无用的练习。这样的代码“有效”,但它返回的小部件将被忽略。

如果您的意图是将按钮显示为某个数据项的表示形式,则需要将自定义委托添加到该视图。代表处理具有非标准要求的项目的可视化和小部件。您必须重新执行QStyledItemDelegate(或QAbstractItemDelegate),并使用setItemDelegateForColumn将其设置在视图的给定列上。

为了满足你的好奇心:

QObject,并且从中获得是不可拷贝,因此类不能被直接存储在QVariant。相反,你可以存储一个共享指针到对象:

typedef QSharedPointer<QPushButton> QPushButtonPtr; 
Q_DECLARE_METATYPE(QPushButtonPtr) 

... 

QVariant ActionSqlRelationModel::data(const QModelIndex &index, int role) const 
{ 
    if (role == Qt::DisplayRole) 
    { 
     return QPushButtonPtr(new QPushButton); 
    } 
    return QSqlRelationModel::data(index, role); // underlying class's data 
} 

我不太清楚你想通过在模型中存储按钮来实现什么。这样做当然可以,除非没有任何视图会知道如何处理您提供给他们的按钮。

+0

谢谢你的回答。我认为你的安抚者是我想要的,但我不明白你在说什么。 我将尝试了解QIdentitityProxyModel是如何工作的。 也想想使用Qptr。 – Woody

+0

@Woody一个'QIdentityProxyModel'是一个代理:它将请求转发给源模型,然后你可以用你认为合适的方式修改请求。通过派生'QIdentityProxyModel',你可以使用任何你想要的源模型。通过直接从源模型派生,您仅限于那一个模型,而没有其他模型。使用共享指针存储小部件是将小部件存储在“QVariant”中的唯一方式,但我仍然问:为什么要将小部件存储在“QVariant”和模型中? **没有现有的视图可以使用这样的小部件!** –

+0

我希望我可以让一行可以被按下或检查。 通过按下该行,它可以显示一个新的小部件。 这就是我想要的。 您对QIdentityProxyModel函数的解释很有趣。 我无法理解模型代理的含义。 – Woody