[Solved] Subclassing QAbstractTableModel
-
I have got implemented all the virtual function than subclassing QAbstractTableModel needs, anyway I can't see anything. Just an empty table.
I made a simple example which reproduces this issues:
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QAbstractTableModel>namespace Ui {
class MainWindow;
}//////////////////////////////////////////////////
/// \brief The MainWindow class
class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();private:
Ui::MainWindow *ui;
};//////////////////////////////////////////////////
/// \brief The ThreadModel class
class ThreadModel : public QAbstractTableModel
{
Q_OBJECTpublic:
explicit ThreadModel(QObject *parent = 0);
~ThreadModel();int rowCount(const QModelIndex&/* parent = QModelIndex()*/) const override; int columnCount(const QModelIndex&/* parent = QModelIndex()*/) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
protected:
QList<QList<int>> threadList;
};#endif // MAINWINDOW_H
@@#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <sstream>
using namespace std;////////////////////////////////////////////////
/// \brief The ThreadDetail class
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);ThreadModel model; ui->tableView->setModel(&model);
}
MainWindow::~MainWindow()
{
delete ui;
}//////////////////////////////////////////////////
/// \brief The ThreadModel class
ThreadModel::ThreadModel(QObject parent/ = 0*/)
{
QList<int> column1;
column1.push_back(10);
column1.push_back(20);
column1.push_back(30);
column1.push_back(40);threadList.push_back(column1); QList<int> column2; column2.push_back(50); column2.push_back(60); column2.push_back(70); column2.push_back(80); threadList.push_back(column2);
}
ThreadModel::~ThreadModel()
{
}int ThreadModel::rowCount(const QModelIndex&/* parent*/) const
{
return threadList[0].size();
}int ThreadModel::columnCount(const QModelIndex&/* parent*/) const
{
return threadList.size();
}QVariant ThreadModel::data(const QModelIndex &index, int role) const
{
if (role == Qt::DisplayRole)
return threadList[index.column()][index.row()];return QVariant::Invalid;
}
QVariant ThreadModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole)
{
stringstream ss;
if (orientation == Qt::Horizontal)
{
ss << "H_" << section;
return QString(ss.str().c_str());
}
else if (orientation == Qt::Vertical)
{
ss << "H_" << section;
QString debug = QString(ss.str().c_str());
return QString(ss.str().c_str());
}
}return QVariant::Invalid;
}
@What else do I need to do? :S
-
Hi,
If the role is not something you handle, return the base class function's implementation otherwise your view won't have any information to show you anything
-
What do you mean with "handling the rol"? What else do I need to do?
-
@ if (role == Qt::DisplayRole)@
You only handle DisplayRole, returning QVariant::Invalid for every other role just gives the views nothing to work on.
What to do ? What I already wrote, for every other role return the base class implementation result of data and headerData
-
First, you CAN'T to return the base class implementation, because it's PURE virtual. You know, the data function is = 0.
And second, even no handling the rol (without condition) it shows nothing. -
Yes you can. You can have have a pure virtual function with a default implementation which is not the case for QAbstractTableModel.
Anyway, you are missing some checks like e.g. the validity for the index given as a parameter. Did you also ensure that all your methods are called ?
You can have a look at the Pixelator example, it uses a custom QAbstractTableModel
-
Let's see if we are talking about the same. If we have:
@#include <iostream>
using namespace std;class A
{
public:
virtual void foo() = 0; // Now, you NEED to override this method!
};void A::foo()
{
cout << "A::foo" << endl;
}class B : public A
{
public:
void foo() override; // Overriding base foo. You get a compiling error if not!:
// Cannot declare variable 'b' to be of abstract type 'B' B b; because the following virtual functions are pure within 'B'
};void B::foo()
{
cout << "B::foo" << endl;
}int main(int argc, char *argv[])
{
B b;b.foo(); return 0;
}@
As I said before, I can't to call a pure virtual function (=0). You need to override it on its derived class.
-
I stumbled upon a similar problem when reading the "Model/View Tutorial":http://qt-project.org/doc/qt-5/modelview.html . One of your problem(s) might be, that you create a Stack-variable "model" in your MainWindow constructor, which you then pass to the tableView as model. When the constructor is done, the Stack-variable won't exist anymore.
You could try allocating "model" on the heap and see if this is fixing your problem. I.e. change
@MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);ThreadModel model; ui->tableView->setModel(&model);
}@
... to ...
@MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);ThreadModel *model = new ThreadModel(); ui->tableView->setModel(model);
}@
-
yetanotherbender has the right solution, I missed that one in your code.
As for our little understanding problem:
@
#include <iostream>
using namespace std;class A
{
public:
virtual void foo() = 0; // Now, you NEED to override this method! << Correct and agreed
};void A::foo()
{
cout << "A::foo" << endl;
}class B : public A
{
public:
void foo() override; // Overriding base foo. You get a compiling error if not!: << still correct and agreed
};void B::foo()
{
A::foo() // If your B class doesn't do anything special you can call the base class default implementation
}int main(int argc, char *argv[])
{
B b;b.foo(); return 0;
}
@ -
[quote author="yetanotherbender" date="1403608883"]You could try allocating “model” on the heap and see if this is fixing your problem[/quote]
Great! That fixed the problem! Thank you SO F*much!! :D
SGaist, thank you for trying and being pacient!! :)
-
You're welcome !
Happy Qt coding ! :)