2
votes

I'm using a QSqlTableModel to get the data from the required table, and I'm rendering it in the GUI using QTableView. The problem that I have now is that I want to change different fields (convert them) from the existing value to another one (enum -> String). For example an existing value of 1 should be displaied as ERROR in the column of QTableView.

My understanding (correct me if I'm wrong) is that I should use delegates.

backupTableView->setItemDelegateForColumn(4, new StatusFormatDelegate());

Column that should be changed in this case is #4.

Is there another way to implement this and in both cases (yes/no) could I get an example?

P.S. The data shouldn't be editable.

Until now the StatusFormatDelegate should be something like this:

class StatusFormatDelegate : public QStyledItemDelegate
{
public:
    StatusFormatDelegate (quint64 dataFromQTableView, QObject *parent = 0) :
  QStyledItemDelegate(parent),
  columnData_(dataFromQTableView)
 {
 }

 virtual QString displayText(const QVariant & value, const QLocale & locale ) const
 {
  Q_UNUSED(locale);
  switch(columnData_){
  case JobStatus_Failed:        return "Failed";
  case JobStatus_Finished:      return "Finished";
  case JobStatus_InProgress:    return "In progress";
  case JobStatus_NotStarted:    return "Not started";
  default:                      return "Unknown type";
  }
 }

private:
 quint64 columnData_;

};

This is the method that creates the Model -> View

void TransferHistory::fillBackUpPageFromDb()
{
    connectToDb();
    QSqlTableModel *model = new QSqlTableModel(this, db);
    model->setTable("backup_history");
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();
    model->setHeaderData(0, Qt::Horizontal, tr("Id"));
    model->setHeaderData(1, Qt::Horizontal, tr("File"));
    model->setHeaderData(2, Qt::Horizontal, tr("Size"));
    model->setHeaderData(3, Qt::Horizontal, tr("Back-up Time"));
    model->setHeaderData(4, Qt::Horizontal, tr("Status"));

    ui->backupTableView = new QTableView(this->ui->tabWidget->currentWidget());
    ui->backupTableView->setModel(model);
    ui->backupTableView->hideColumn(0);
    ui->backupTableView->setShowGrid(false);
    ui->backupTableView->setSortingEnabled(true);
    int width = ui->tabWidget->currentWidget()->width();
    ui->backupTableView->setFixedSize(ui->tabWidget->currentWidget()->size());

    **ui->backupTableView->setItemDelegateForColumn(4, new StatusFormatDelegate(someData, this));**
    ui->backupTableView->setColumnWidth(1, static_cast<int>(FILECOLUMNWIDTH_PERCENT * width));
    ui->backupTableView->setColumnWidth(2, static_cast<int>(SIZECOLUMNWIDTH_PERCENT * width));
    ui->backupTableView->setColumnWidth(3, static_cast<int>(TIMECOLUMN_PERCENT * width));
    ui->backupTableView->setColumnWidth(4, static_cast<int>(STATUSCOLUMN_PERCENT * width) - qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent) - 2);
    ui->backupTableView->show();
}
2
i find this question very unclear - ldgorman
please try to explain why you think the use of delegates is appropriate - ldgorman
Hi, I'm really new to QT, so if there is another way to solve the issue without using delegates I'll be happy to implement it - Bogdan
well, one thing. did you know that enums are returned as strings, and not numbers? - ldgorman
i think you are way over complicating things. Are you just trying to get data from a sql db, then change the format of those values? - ldgorman

2 Answers

1
votes

Found the needed solution, there isn't a need of delegates neither of queries, just the override of the QSqlTableModel data method for the Qt::DisplayRole and the needed column:

class MySubClassedSqlTableModel : public QSqlTableModel
{
    Q_OBJECT
public:
    MySubClassedSqlTableModel(QObject * parent = 0, QSqlDatabase db = QSqlDatabase())
    : QSqlTableModel(parent,db) {};

    QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const
    {
        QVariant value = QSqlQueryModel::data(index, role);

        if (role==Qt::DisplayRole &&
            index.column() == 4) {
            QString valStr = value.toString();
            bool ok;
            int valInt = valStr.toInt(&ok);
            if(ok) {
              switch(valInt){
              case JobStatus_Failed:        return QVariant(QString("Failed"));
              case JobStatus_Finished:      return QVariant(QString("Finished"));
              case JobStatus_InProgress:    return QVariant(QString("In progress"));
              case JobStatus_NotStarted:    return QVariant(QString("Not started"));
              default:                      return QVariant(QString("Unknown type"));
              }
          }
        }

        return QSqlTableModel::data(index,role);
    }
};

And the usage of my class with the implemented QTableView :

    connectToDb();
    MySubClassedSqlTableModel *model = new MySubClassedSqlTableModel(this, db);
    model->setTable("backup_history");
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    model->select();
    model->setHeaderData(0, Qt::Horizontal, tr("Id"));
    model->setHeaderData(1, Qt::Horizontal, tr("File"));
    model->setHeaderData(2, Qt::Horizontal, tr("Size"));
    model->setHeaderData(3, Qt::Horizontal, tr("Back-up Time"));
    model->setHeaderData(4, Qt::Horizontal, tr("Status"));

    ui->backupTableView = new QTableView(this->ui->tabWidget->currentWidget());
    ui->backupTableView->setModel(model);
    ui->backupTableView->hideColumn(0);
    ui->backupTableView->setShowGrid(false);
    ui->backupTableView->setSortingEnabled(true);
    ui->backupTableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    int width = ui->tabWidget->currentWidget()->width();
    ui->backupTableView->setFixedSize(ui->tabWidget->currentWidget()->size());

    ui->backupTableView->setColumnWidth(1, static_cast<int>(FILECOLUMNWIDTH_PERCENT * width));
    ui->backupTableView->setColumnWidth(2, static_cast<int>(SIZECOLUMNWIDTH_PERCENT * width));
    ui->backupTableView->setColumnWidth(3, static_cast<int>(TIMECOLUMN_PERCENT * width));
    ui->backupTableView->setColumnWidth(4, static_cast<int>(STATUSCOLUMN_PERCENT * width) - qApp->style()->pixelMetric(QStyle::PM_ScrollBarExtent) - 2);
    ui->backupTableView->show();
0
votes

to get data from a sql db, do the following:

connect to the db:

QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("mozart.konkordia.edu");
    db.setDatabaseName("musicdb");
    db.setUserName("gbatstone");
    db.setPassword("T17aV44");
    if (!db.open()) {
        QMessageBox::critical(0, QObject::tr("Database Error"),
                              db.lastError().text());

select data from the db

QSqlQuery query("SELECT aField FROM aTable");
     while (query.next()) {
         QString fieldData = query.value(0).toString();

     }

use the different 'to' methods to change the type of the return value.

see more here and here