Преобразование данных из QSqlTableModel в человеческую форму в QTableView (enum - ›String)

Я использую QSqlTableModel для получения данных из требуемой таблицы и визуализирую их в графическом интерфейсе с помощью QTableView. Проблема, которая возникла у меня сейчас, заключается в том, что я хочу изменить разные поля (преобразовать их) с существующего значения на другое (enum -> String). Например, существующее значение 1 должно отображаться как ОШИБКА в столбце QTableView.

Насколько я понимаю (поправьте меня, если я ошибаюсь), я должен использовать делегатов.

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

Столбец, который следует изменить в этом случае, - это №4.

Есть ли другой способ реализовать это, и в обоих случаях (да / нет) я могу получить пример?

P.S. Данные не должны редактироваться.

До сих пор StatusFormatDelegate должен выглядеть примерно так:

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_;

};

Это метод, который создает Модель -> Просмотр

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();
}

person Bogdan    schedule 18.08.2014    source источник
comment
я нахожу этот вопрос очень неясным   -  person ldgorman    schedule 18.08.2014
comment
пожалуйста, попробуйте объяснить, почему вы думаете, что использование делегатов уместно   -  person ldgorman    schedule 18.08.2014
comment
Привет, я новичок в QT, поэтому, если есть другой способ решить проблему без использования делегатов, я буду рад его реализовать.   -  person Bogdan    schedule 18.08.2014
comment
ну одно. знаете ли вы, что перечисления возвращаются как строки, а не числа?   -  person ldgorman    schedule 18.08.2014
comment
Я думаю, вы слишком усложняете вещи. Вы просто пытаетесь получить данные из sql db, а затем изменить формат этих значений?   -  person ldgorman    schedule 18.08.2014
comment
В базе данных это числа, поэтому QSqlTableModel возвращает числа. (в моем случае)   -  person Bogdan    schedule 18.08.2014
comment
Это существующее приложение. любое изменение формата повлияет на многие другие части ....   -  person Bogdan    schedule 18.08.2014
comment
верно, например, вам не нужно использовать qsqltablemodel   -  person ldgorman    schedule 18.08.2014
comment
в старой версии используется: treeWidgetItemList. И мы хотели бы использовать QSqlTableModel, чтобы данные считывались напрямую из базы данных без проблем.   -  person Bogdan    schedule 18.08.2014


Ответы (2)


Нашли необходимое решение, нет необходимости ни в делегатах, ни в запросах, просто переопределение метода данных QSqlTableModel для Qt :: DisplayRole и нужного столбца:

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);
    }
};

И использование моего класса с реализованным 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();
person Bogdan    schedule 19.08.2014

чтобы получить данные из базы данных sql, сделайте следующее:

подключиться к БД:

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());

выберите данные из базы данных

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

     }

используйте разные методы 'to', чтобы изменить тип возвращаемого значения.

подробнее здесь и здесь

person ldgorman    schedule 18.08.2014
comment
Проблема в том, что мне не нужно только одно поле, мне нужна вся база данных в графическом интерфейсе, поэтому мы выбираем QSqlModel (table) с использованием QTableView. Необходимо изменить только 2 столбца (один с int, который нужно проанализировать в строку, а другой с меткой времени, которую нужно преобразовать в человеческую форму). Из-за этого я хотел спросить, есть ли шанс использовать делегаты, поскольку их можно установить на столбцах. (setItemDelegateForColumn) - person Bogdan; 18.08.2014