mardi 5 mars 2019

How to change the entire format of a QTableView using a QAction

I am trying to pass from the print below (for which currently I am able to change and accept the format of each cell of a specific column of a QTableView doing it by hand for each cell).

Also the QTableView is formed of the following columns to be prcise: id - name - save - ACoord - BCoord - CCoord - DCoord and I only put the print screen of the interested part:

Manual

Into changing the entire column in one time using a QAction like below, which would be the behavior I am trying to achieve:

QAction_change_column

See below the most important part of the code that I am trying to achieve (I only put the code for one column):

edittabledialog.h

private slots:
    void currentColumnChanged(const QModelIndex &mi);
    void autoSelectMagicColumn();
private:
    Ui::editTableDialog *ui;
    QSqlTableModel *mModel;
    QAction *mChangeFormat;
    QPoint chanheInOneTime(QString input);
    const int magicColumnIndexACoord = 3;

edittabledialog.cpp

editTableDialog::editTableDialog(const QString &tableName, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::editTableDialog)
{
    ui->setupUi(this);
    mChangeFormat = new QAction(QIcon(":"), tr("from format 123:123 to (123,123)"), this);
    mModel = new QSqlTableModel(this);
    mModel->setEditStrategy(QSqlTableModel::OnManualSubmit);
    mModel->setTable(tableName);
    mModel->select();
    ui->tableView->setModel(mModel);
    connect(ui->tableView->selectionModel(), SIGNAL(currentColumnChanged(const QModelIndex &, const QModelIndex &)),
            this, SLOT(currentColumnChanged(const QModelIndex &)));

    ui->tableView->setContextMenuPolicy(Qt::ActionsContextMenu);
    ui->tableView->addActions({mChangeFormat});

    connect(mChangeFormat, &QAction::triggered, [&]() {
        int row = -1, column = -1;
        QString reference, type;
        QModelIndex index;
        Param param;
        for(int i = 0; i < ui->tableView->model()->columnCount(); i++)
        {
          if(ui->tableView->model()->headerData(i, Qt::Horizontal).toString() == "ACoord") {
              column = i;
              type = "ACoord";
              param.mACoord.setX(chanheInOneTime(index.sibling(row,3).data().toString()).x()); // <-- Debugger Error Here 
              param.mACoord.setY(chanheInOneTime(index.sibling(row,3).data().toString()).y());
              mModel->submitAll();
              ui->tableView->show();
          }
        }
    });
}

void editTableDialog::currentColumnChanged(const QModelIndex &mi)
{
    const int col = mi.column();
    if (col == magicColumnIndexACoord) {
       QTimer::singleShot(100, this, SLOT(autoSelectMagicColumn()));
    }
}

void editTableDialog::autoSelectMagicColumn()
{
    if (ui->tableView->selectionModel()->currentIndex().column() == magicColumnIndexACoord) {
        ui->tableView->selectColumn(magicColumnIndexACoord);
    }
}
QPoint editTableDialog::chanheInOneTime(QString input)
{
    QPoint output;

    if(input.contains('('))
    {
        output.setX(input.remove('(').remove(')').remove(',').split(" ")[0].toInt());
        output.setY(input.remove('(').remove(')').remove(',').split(" ")[1].toInt());
    }
    else
    {
        output.setX(input.split(":")[0].toInt());
        output.setY(input.split(":")[1].toInt()); // <-- Debugger Error Here 
    }
    return output;
}

bool editTableDialog::submitData()
{
    if(!mModel->submitAll()) {
        QMessageBox::warning(this, "Submit Error", "Failed to write to table. Error was \"" + mModel->lastError().text() + "\"");
        return false;
    } else
    { return true; }
}

void editTableDialog::on_acceptBtn_clicked()
{ if(submitData())
        accept(); }

Param comes from the following class parameters.h:

typedef struct Param
{
    int mId;
    QString mName;
    QByteArray mSave;
    QPoint mACoord;
    QPoint mBCoord;
    QPoint mCCoord;
    QPoint mDCoord;
} Param;

class Parameters
{
public:
    Parameters(Param newdata);
    Parameters(int id, const QString &name,
               QPoint aCoord, QPoint bCoord, QPoint cCoord, QPoint dCoord,
               const QByteArray &save);
    QPoint mACoord() const { return data.mACoord; }
    QPoint mBCoord() const { return data.mBCoord; }
    QPoint mCCoord() const { return data.mCCoord; }
    QPoint mDCoord() const { return data.mDCoord; }
    void setData(Param ndat) { data = ndat; }
private:
    Param data;
};

I have seen this post. Also this post but this mentions to use a QStyledItemDelegate, however I am not sure it could be the right choice.

And the compiler in debug mode says :ASSERT failure in QList<T>::operator[]: "index out of range

How to do that? Please shed light on this issue if possible.

Aucun commentaire:

Enregistrer un commentaire