Program Done in QT C++ crash when running event

Asked

Viewed 25 times

-2

I’m creating a program in QT with C++ for Sales control, but in the Consultation Dialogue I have a problem. In it I have a button click event, where it should open the database and update information, but the program crashes and does not show any error, I have tried to leave only variable assignments (taking the database) but it crashes the same way!!!

consultations. h

#ifndef CONSULTAS_H
#define CONSULTAS_H
#include "connection.h"
#include <QMessageBox>
#include <QTableWidget>
#include <QString>
#include <QList>
#include <QLineEdit>
#include <QDialog>

namespace Ui {
class consultas;
}

class consultas : public QDialog
{
    Q_OBJECT

public:
    explicit consultas(QWidget *parent = nullptr);
    ~consultas();
    Connection con;
    QString asc_desc = "ASC";
    QString nome;
    QString tel;
    QString ende;
    QString mail;
    int cont = 0;
    int id;
    void insert_table(QTableWidget *tabela, QString query_text);
    void insert_lineedit(QString query_text, QList<QLineEdit*> items);

private slots:
    void on_central_currentChanged(int index);

    void on_radio_asc_clicked();

    void on_radio_desc_clicked();

    void on_tabela_itemSelectionChanged();

    void on_btn_save_clicked();

private:
    Ui::consultas *ui;
};

#endif // CONSULTAS_H

cpp consultations.

#include "consultas.h"
#include "ui_consultas.h"

consultas::consultas(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::consultas)
{
    ui->setupUi(this);
}

consultas::~consultas()
{
    delete ui;
}

void consultas::insert_table(QTableWidget *tabela, QString query_text) {
    cont = 0;
    if (con.init()) {
        QSqlQuery query;
        query.prepare(query_text);
        if (query.exec()) {
            while (query.next()) {
               tabela->insertRow(cont);
               tabela->setItem(cont, 0, new QTableWidgetItem(query.value(0).toString()));
               tabela->setItem(cont, 1, new QTableWidgetItem(query.value(1).toString()));
               tabela->setItem(cont, 2, new QTableWidgetItem(query.value(2).toString()));
               tabela->setItem(cont, 3, new QTableWidgetItem(query.value(3).toString()));
               tabela->setItem(cont, 4, new QTableWidgetItem(query.value(4).toString()));
               tabela->setRowHeight(cont, 20);
               cont++;
            }
            con.exit();
        }
        else {
            QMessageBox::warning(this, "Erro ao Exibir Registros", "Erro ao Exibir Registros, Tente Novamente mais Tarde");
            con.exit();
        }
    }
    else {
        QMessageBox::critical(this, "Erro ao Abrir Banco de Dados", "Erro ao Abrir Banco de Dados, Tente Novamente mais Tarde");
    }
}

void consultas::insert_lineedit(QString query_text, QList<QLineEdit*> items) {
    int query_cont = 1;
    if (con.init()) {
        QSqlQuery query;
        query.prepare(query_text);
        if (query.exec()) {
            query.first();
            while (query_cont < items.size()) {
                items[query_cont]->setText(query.value(query_cont).toString());
                query_cont++;
            }
            con.exit();
        }
        else {
            QMessageBox::warning(this, "Erro ao Exibir Registros", "Erro ao Exibir Registros, Tente Novamente mais Tarde");
            con.exit();
        }
    }
    else {
        QMessageBox::critical(this, "Erro ao Abrir Banco de Dados", "Erro ao Abrir Banco de Dados, Tente Novamente mais Tarde");
    }
}

void consultas::on_central_currentChanged(int index)
{
    if (index == 0) {
        ui->tabela->setRowCount(0);
        insert_table(ui->tabela, "SELECT * FROM tb_fornecedor ORDER BY id_fornec "+asc_desc);
        ui->tabela->horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
        ui->tabela->verticalHeader()->resizeSections(QHeaderView::ResizeToContents);
    }
}

void consultas::on_radio_asc_clicked()
{
    asc_desc = "ASC";
}

void consultas::on_radio_desc_clicked()
{
    asc_desc = "DESC";
}

void consultas::on_tabela_itemSelectionChanged()
{
    id = ui->tabela->item(ui->tabela->currentRow(), 0)->text().toInt();
    QList<QLineEdit*> lines = {ui->nome, ui->nome, ui->tel, ui->ende, ui->mail};
    insert_lineedit("SELECT * FROM tb_fornecedor WHERE id_fornec='"+QString::number(id)+"' ORDER BY id_fornec "+asc_desc, lines);
}

void consultas::on_btn_save_clicked()
{


    if (con.init()) {
        QSqlQuery query;
        query.prepare("UPDATE tb_fornecedor SET nome_fornec='"+nome+"', telefone_fornec='"+tel+"', endereco_fornec='"+ende+"', email_fornec='"+mail+"'"
                      "WHERE id_fornec='"+QString::number(id)+"'");
        if (query.exec()) {
            ui->tabela->setItem(ui->tabela->currentRow(), 1, new QTableWidgetItem(nome));
            ui->tabela->setItem(ui->tabela->currentRow(), 2, new QTableWidgetItem(tel));
            ui->tabela->setItem(ui->tabela->currentRow(), 3, new QTableWidgetItem(ende));
            ui->tabela->setItem(ui->tabela->currentRow(), 4, new QTableWidgetItem(mail));
            QMessageBox::information(this, "Informações Salvas com Sucesso", "Informações Foram Alteradas e Salvas com Sucesso");
        }
    }
}

Connection. h

#ifndef CONNECTION_H
#define CONNECTION_H
#include <QtSql>
#include <QSqlQuery>

class Connection {
public:
    QSqlDatabase database;
    Connection() {
        database = QSqlDatabase::addDatabase("QSQLITE");
    }
    void exit() {
        database.close();
    }
    bool init() {
        QString local = qApp->applicationDirPath();
        QString dataname = local + "/db/database.db";
        database.setDatabaseName(dataname);
        if (!database.open()) {
            return false;
        }
        else {
            return true;
        }
    }
};

#endif // CONNECTION_H

error

13:51:32: The program has unexpectedly finished.
13:51:32: The process was ended forcefully.
13:51:32: /home/paulo/Área de trabalho/Qt-Projects/SistemaControleNotas/build-SistemaControleNotas-Desktop-Debug/SistemaControleNotas crashed.

Does anyone know why the program crashes? Thank you very much!

1 answer

1

what is causing the application crash is the on_tabela_itemSelectionChanged slot,

id = ui->tabela->item(ui->tabela->currentRow(), 0)->text().toInt();

it turns out that the method currentRow() returns -1 in situations where there are no items selected in the table, and this is exactly what will occur when you clean the table in this section:

void consultas::on_central_currentChanged(int index){
if (index == 0) {
    ui->tabela->setRowCount(0);// <-

if there is an item selected in the table while cleaning you will fire the Signal Qtablewidget::itemSelectionChanged().

the problem in this case is that the function *Qtablewidgetitem Qtablewidget::item(int Row, int column) const, returns a null pointer if no index is reported.

Returns the item for the Given Row and column if one has been set; otherwise Returns nullptr.

in sequence you will try to access the text() function in this null pointer.

an alternative to prevent this would be:

void consultas::on_tabela_itemSelectionChanged()
{

    if( -1 != ui->tabela->currentRow())
    {
        QTableWidgetItem * item = ui->tabela->item(ui->tabela->currentRow(), 0);
        if(nullptr == item)
        {
            return;
        }
        bool conversao_ok = false;
        id = item->text().toInt(&conversao_ok);

        if(!conversao_ok)
        {
            return;
        }
        QList<QLineEdit*> lines = {ui->nome, ui->nome, ui->tel, ui->ende, ui->mail};
        insert_lineedit("SELECT * FROM tb_fornecedor WHERE id_fornec='"+QString::number(id)+"' ORDER BY id_fornec "+asc_desc, lines);
    }
}

Some other recommendations, there is an error in the slot void queries::on_btn_save_clicked(), it will always clean the data from the records in the database, because you are building the query using the attributes

QString nome;
QString tel;
QString ende;
QString mail;

that are not changed during the course of your code, at the time you make the change so that the values are pulled from the user inputs take care to validate the fields, because you run the risk of leaving your code vulnerable to Sqlinjection, or even something simpler. if a user informs for example the address "Rua Pedra D'Água" your query will give error and will not be made the change. another example would be if a malicious user puts the supplier’s name as

supplier 2',id_fornec='123

could thus change your database data that initially you would not allow the change

Browser other questions tagged

You are not signed in. Login or sign up in order to post.