Как использовать QAction для преобразования определенного столбца QTableView из формата A в формат B
Я пытаюсь использовать QAction для преобразования конкретного столбца QTableView из текущего формата xxx:xxx в другой формат (xxx,xxx) и обратно.
Я подготовил небольшое минимальное приложение, которое несет в себе именно ту проблему, которая у меня есть. Приложение состоит из:
1) Главное окно, которое несет QTableView с:
Id | имя | возраст | зарплата | координировать
Также для полноты здесь показан экран печати GUI:
Кроме того, экран печати того, чего я пытаюсь достичь, также показан ниже, обратите внимание, что как только я нажимаю на столбец "координаты", он загорается, и при щелчке правой кнопкой мыши я пытаюсь изменить формат с xxx:xxx на (xxx, ххх) но не работает
Я пытаюсь изменить последний столбец "координата" из формата ххх: ххх в формат (ххх, ххх) и обратно. Когда вы щелкаете по любой ячейке последнего столбца, можно выбрать "координату" всего столбца.
Что я пробовал до сих пор:
Я попытался изменить формат, следуя этому источнику, который был полезен, но не полностью решил проблему.
Кроме того, я реализовал часть этого решения, которая пыталась ввести десятичные числа в ячейки. Однако в моем случае у меня нет QStyledItemDelegate
но просто QAction
,
Также это была самая близкая помощь, которую я мог найти. В этом примере предлагается QStyledItemDelegate
тоже, но это не то, чего я пытаюсь достичь.
Также я написал QPoint Widget::parseCoordStringForTheTable(QString input)
который принимает определенные форматы, но я не уверен, как обработать это исключение.
Это полный MCVE, поэтому его нужно только скопировать и вставить, и он должен работать сразу:
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQueryModel>
namespace Ui {
class Widget;
}
class QSqlQueryModel;
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_add_clicked();
void on_close_clicked();
void on_modify_clicked();
void currentColumnChanged(const QModelIndex &mi);
void autoSelectMagicColumn();
private:
Ui::Widget *ui;
QSqlDatabase mDatabase;
QSqlQueryModel *mModel;
QAction *mTurnIntoExcelData;
QPoint parseCoordStringForTheTable(QString input);
const int magicColumnIndex = 4;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QtSql/QSqlQueryModel>
#include <QSqlError>
#include <QSqlQuery>
#include <QMessageBox>
#include <QInputDialog>
#include <QTimer>
#include <QAction>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
mTurnIntoExcelData = new QAction(QIcon(":"), tr("Turn into Excel format"), this);
ui->tableView->setContextMenuPolicy(Qt::ActionsContextMenu);
ui->tableView->addActions({mTurnIntoExcelData});
connect(mTurnIntoExcelData, &QAction::triggered, [&]() {
int row = -1, column = -1;
QString reference;
QString type;
QModelIndex index;
QPoint data;
for(int i = 0; i < ui->tableView->model()->columnCount(); i++)
{
if(ui->tableView->model()->headerData(i, Qt::Horizontal).toString() == "coordinate") {
column = i;
type = "coordinate";
data.setX(parseCoordStringForTheTable(index.sibling(row,4).data().toString()).x());
data.setY(parseCoordStringForTheTable(index.sibling(row,4).data().toString()).y());
//mModel->submitAll();
ui->tableView->show();
}
}
QModelIndexList selection = ui->tableView->selectionModel()->selectedColumns();
if (selection.count() > 0) {
QModelIndex index = selection.at(0);
row = index.row();
}
if(row < 0 || column < 0)
{
QMessageBox::warning(this, "Warning", "DoubleCheck - Didnt work");
}
else {
reference = ui->tableView->model()->data(ui->tableView->model()->index(row,column)).toString();
if(reference == "No Coordinates Present")
return;
}
});
mDatabase = QSqlDatabase::addDatabase("QSQLITE");
mDatabase.setDatabaseName("/path/to/Desktop/tmp/Stackru.db");
if(!mDatabase.open()) {
QMessageBox::critical(this, "Error", mDatabase.lastError().text());
return;
}
QSqlQuery qry;
if (!qry.exec("CREATE TABLE IF NOT EXISTS persona " \
"(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," \
"name TEXT NOT NULL," \
"age INTEGER NOT NULL," \
"salary DOUBLE NOT NULL, "
"coordinate TEXT NOT NULL)")) {
QMessageBox::critical(this, "Error", qry.lastError().text());
return;
}
mModel = new QSqlQueryModel(this);
mModel->setQuery("SELECT * FROM persona");
ui->tableView->setModel(mModel);
connect(ui->tableView->selectionModel(), SIGNAL(currentColumnChanged(const QModelIndex &, const QModelIndex &)),
this, SLOT(currentColumnChanged(const QModelIndex &)));
}
Widget::~Widget()
{delete ui;}
void Widget::on_add_clicked()
{
QSqlQuery qry;
if (!qry.exec(QString("INSERT INTO persona (name,age,salary,coordinate)"\
"VALUES ('%1',%2,%3,%4)").
arg(ui->name->text()).
arg(ui->age->value()).
arg(ui->salary->value()).
arg(ui->coordinate->text()))) {
QMessageBox::critical(this, "Error", qry.lastError().text());
return;
}
mModel->setQuery("SELECT * FROM persona");
ui->tableView->setModel(mModel);
}
void Widget::on_close_clicked()
{close();}
void Widget::on_modify_clicked()
{
auto uploadInt = [&](QWidget *parent, const QString &title, const QString &msg, int valor) {
bool ok;
int res = QInputDialog::getInt(parent, title, msg, valor,
-2147483647, 2147483647, 1, &ok);
if(ok) { return res; }
return valor;
};
auto uploadName = [&](QWidget *parent, const QString &name) {
bool ok;
auto res = QInputDialog::getText(parent, "Name", "Name Input",
QLineEdit::Normal, name, &ok);
if(ok) { return res; }
return name;
};
auto uploadSalary = [&](QWidget *parent, double salary) {
bool ok;
double res = QInputDialog::getDouble(parent, "Salary", "Salary Input", salary,
-2147483647, 2147483647, 3, &ok);
if(ok) { return res; }
return salary;
};
auto uploadCoord = [&](QWidget *parent, int coord) {
bool ok;
int res = QInputDialog::getInt(parent, "Coordinate", "Input Coordinate", coord,
-2147483647, 2147483647, 1, &ok);
if(ok) { return res; }
return coord;
};
int col = ui->tableView->currentIndex().column();
int row = ui->tableView->currentIndex().row();
QString sql;
if(col == 0) {
int id = mModel->index(row, col).data().toInt();
sql = QString("UPDATE persona SET id = %1 WHERE id = %2").
arg(uploadInt(this, "Id", "Id Input", id)).arg(id);
} else if (col == 1) {
auto name = mModel->index(row, col).data().toString();
sql = QString("UPDATE persona SET name = '%1' WHERE name LIKE '%2'").
arg(uploadName(this, name)).arg(name);
} else if (col == 2) {
int age = mModel->index(row, col).data().toInt();
sql = QString("UPDATE persona SET age = %1 WHERE age = %2").
arg(uploadInt(this, "Age", "Age Input", age)).arg(age);
} else if (col == 3) {
double salary = mModel->index(row, col).data().toDouble();
sql = QString("UPDATE persona SET salary = %1 WHERE salary = %2").
arg(uploadSalary(this, salary)).arg(salary);
} else if (col == 4) {
int coordinate = mModel->index(row, col).data().toInt();
sql = QString("UPDATE persona SET coordinate = %1 WHERE salary = %2").
arg(uploadCoord(this, coordinate)).arg(coordinate);
}
QSqlQuery qry;
qry.exec(sql);
mModel->setQuery("SELECT * FROM persona");
}
void Widget::currentColumnChanged(const QModelIndex &mi) {
const int col = mi.column();
if (col == magicColumnIndex) {
QTimer::singleShot(100, this, SLOT(autoSelectMagicColumn()));
}
}
void Widget::autoSelectMagicColumn()
{
if (ui->tableView->selectionModel()->currentIndex().column() == magicColumnIndex) {
ui->tableView->selectColumn(magicColumnIndex);
}
}
QPoint Widget::parseCoordStringForTheTable(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());
}
return output;
}
Ожидаемый результат: изменить формат одного конкретного столбца, передавая из текущего формата xxx:xxx в формат (xxx,xxx), и повернуть вспять, как только я нажму k в столбце "координата"
Фактически: не работает, потому что ничего не происходит.
Итак, подведем итоги: изображение, показанное ниже, - это то, чего я пытаюсь достичь, последний столбец станет полностью выбираемым, как только пользователь щелкнет в любой ячейке этого конкретного столбца, и щелчком правой кнопки мыши я пытаюсь изменить весь формат столбца от ххх: ххх, до (ххх, ххх):
Любые возможные идеи будут полезны, спасибо.