[Resuelto] Bases de datos QtSql



  • Hola a todos,

    Soy nuevo en Qt, estoy trabajando en un proyecto con bases de datos. He creado una base de datos "Datos1" en la que se encuentran los valores de "id", "Day", "Month" y "Year".

    El problema que tengo es que no sé como podría conseguir que al introducir el "id" en un LineEdit y pulsar Enter me mostrase los datos de "Day" y "Month". Necesito que muestre solo estos dos datos en una QTableWidget.

    Además, también me gustaría que al presionar un botón se guardasen los datos "id", "Month" y "Year" en otra base de datos "Guardados".

    Os dejo los códigos:

    #-------------------------------------------------

    # Project created by QtCreator 2015-09-29T19:26:52

    #-------------------------------------------------

    QT += core gui sql

    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

    TARGET = Partes_Hospital_Clinic
    TEMPLATE = app

    SOURCES += main.cpp
    mainwindow.cpp
    basedialog.cpp

    HEADERS += mainwindow.h
    basedialog.h

    FORMS += mainwindow.ui
    basedialog.ui

    • mainwindow.h:

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H

    #include <QMainWindow>
    #include <QtSql/QSqlDatabase>
    #include <QtSql/QSqlQuery>
    #include <QtSql/QSqlError>

    namespace Ui {
    class MainWindow;
    }

    class MainWindow : public QMainWindow
    {
    Q_OBJECT

    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    /*
    
    void crearTablaDatos2();
    
    void insertarDatos2();
    
    */
    

    private slots:

    void on_pushButton_clicked();
    
    void on_pushButton_2_clicked();
    

    private:
    Ui::MainWindow *ui;
    QSqlDatabase db;
    };

    #endif // MAINWINDOW_H

    • basedialog.h:

    #ifndef BASEDIALOG_H
    #define BASEDIALOG_H

    #include <QDialog>
    #include <QtSql/QSqlDatabase>
    #include <QtSql/QSqlQuery>
    #include <QtSql/QSqlError>

    namespace Ui {
    class BaseDialog;
    }

    class BaseDialog : public QDialog
    {
    Q_OBJECT

    public:
    explicit BaseDialog(QWidget *parent = 0);
    ~BaseDialog();

        void mostrarDatos2();
    

    private:
    Ui::BaseDialog *ui;
    };

    #endif // BASEDIALOG_H

    • main.cpp:

    #include "mainwindow.h"
    #include <QApplication>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
    

    }

    • mainwindow.cpp:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "basedialog.h"

    #include <QDebug>
    #include <QStandardItemModel>

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    qDebug()<<"Aplicación iniciada";
    
    QString nombre;
    nombre.append("Datos1");
    
    db=QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(nombre);
    
    if(db.open()){
        qDebug()<<"Se ha conectado a la base de datos";
    }else{
        qDebug()<<"ERROR. No se ha conectado a la base de datos";
    }
    

    }

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

    /*

    void MainWindow::crearTablaDatos2()
    {
    QString consulta;
    consulta.append("CREATE TABLE IF NOT EXISTS Datos2("
    "id INTEGER PRIMARY KEY,"
    "Day VARCHAR(100),"
    "Month VARCHAR(100),"
    "Year VARCHAR(100)"
    ");");
    QSqlQuery crear;
    crear.prepare(consulta);

    if(crear.exec())
    {
        qDebug()<<"La tabla Datos2 exixte o se ha creado correctamente";
    }else{
        qDebug()<<"ERROR. La tabla Datos2 no exixte o no se ha creado correctamente";
        qDebug()<<"ERROR:"<<crear.lastError();
    }
    

    }

    void MainWindow::insertarDatos2()
    {
    QString consulta;
    consulta.append("INSERT INTO Datos2("
    "id,"
    "Day,"
    "Month,"
    "Year)"
    "VALUES("
    "5,"
    "'5',"
    "'5',"
    "'2015'"
    ");");
    QSqlQuery insertar;
    insertar.prepare(consulta);

    if(insertar.exec())
    {
        qDebug()<<"El dato se ha insertado correctamente";
    }else{
        qDebug()<<"ERROR. El dato no se ha insertado correctamente";
        qDebug()<<"ERROR:"<<insertar.lastError();
    }
    

    }

    */

    void MainWindow::on_pushButton_clicked()
    {
    /*
    crearTablaDatos2();
    insertarDatos2();
    */
    }

    void MainWindow::on_pushButton_2_clicked()
    {
    BaseDialog bs(this);
    bs.setWindowTitle("Database");
    bs.exec();

    }

    • basedialog.cpp:

    #include "basedialog.h"
    #include "ui_basedialog.h"

    #include <QDebug>
    #include <QStandardItemModel>

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

    mostrarDatos2();
    

    }

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

    void BaseDialog::mostrarDatos2()
    {
    QString consulta;
    consulta.append("SELECT*FROM Datos2");
    QSqlQuery mostrar;
    mostrar.prepare(consulta);

        if(mostrar.exec())
        {
            qDebug()<<"Los datos se han mostrado correctamente";
        }else{
            qDebug()<<"ERROR. Los datos no se hana mostrado correctamente";
            qDebug()<<"ERROR:"<<mostrar.lastError();
        }
    
        int columna=0;
    
        while(mostrar.next()){
    
        ui->tableWidgetDatos2->setRowCount(4);
    
    
        QStringList Datos3;
        Datos3<<"Id"<<"Day"<<"Month"<<"Year";
    
        ui->tableWidgetDatos2->setVerticalHeaderLabels(Datos3);
    
            ui->tableWidgetDatos2->insertColumn(0);
            ui->tableWidgetDatos2->setColumnCount(10);
    
            ui->tableWidgetDatos2->setItem(0, 0, new QTableWidgetItem(mostrar.value(0).toByteArray().constData()));
            ui->tableWidgetDatos2->setItem(1, 0, new QTableWidgetItem(mostrar.value(1).toByteArray().constData()));
            ui->tableWidgetDatos2->setItem(2, 0, new QTableWidgetItem(mostrar.value(2).toByteArray().constData()));
            ui->tableWidgetDatos2->setItem(3, 0, new QTableWidgetItem(mostrar.value(3).toByteArray().constData()));
    
            columna++;
        }
    

    }

    ¿Alguien conoce alguna manera de hacerlo?

    Muchas gracias



  • Hola

    El tema de las bases de datos no es demasiado complejo en Qt, ya que trae un montón de clases que se encargan de todo. Lo primero que tienes que hacer es ver la clase QSqlQuery. Revísala que tiene un montón de ejemplos de uso.

    Por ejemplo puedes preparar una consulta más o menos así:

    QSqlQuery query;
    query.prepare("select * from tu_tabla where id=:ID");
    query.bindValue(":ID", ui->tu_line_edit->text().trimmed());
    if(query.exec()){
    // leer los datos
    } else {
    // error al realizar la consulta
    }

    También puedes usar, en vez de un QTableWidget un QTableView y un QSqlTableModel, que tiene un método setFilter que puedes usar para pasarle el id que introduces en el QLineEdit y el mismo modelo te carga los datos que corresponden.

    Para guardar igual, con QSqlQuery puedes hacerlo. Pero si dices que quieres guardar los datos en otra base de datos, tendrás que crear otra conexión, pero no sé lo que querrás hacer, pero no es muy habitual eso, normalmente se tiene todo en la misma base de datos en diferentes tablas.

    No te pongo ningún ejemplo por que estoy de viaje, pero revísate la documentación de todas las clases que te nombré que traen muchos ejemplos y no te costará hacer lo que dices.

    Un Saludo



  • @juanki
    He revisado toda la documentación de QSqlQuery.
    He intentado varias versiones del código que me has pasado y he configurado el código del setItem del QTableWidgets de mil maneras para que me mostrase los datos pero no ha habido manera de que los muestre. Pero creo que sí que consigue leer los datos de la id que le introduzco por el LineEdit.

    • Una de las formas:
    void MainWindow::visualizarUsuarios()
    {
        QSqlQuery qry;
        qry.prepare("SELECT*FROM otra WHERE id=:ID");
        qry.bindValue(":ID", ui->lineEditBueno->text().trimmed());
    
        if(qry.exec())
        {
           ui->tableWidgetMuestra->setColumnCount(5);
    
                ui->tableWidgetMuestra->insertColumn(0);
    
                ui->tableWidgetMuestra->setItem(0, 0, new QTableWidgetItem(qry.value(1).toByteArray().constData()));
    
                ui->tableWidgetMuestra->setItem(0, 1, new QTableWidgetItem(qry.value(2).toByteArray().constData()));
              
            qDebug()<<"Los datos se han qry correctamente";
    
       } else {
           qDebug()<<"ERROR. Los datos no se hana qry correctamente";
           qDebug()<<"ERROR:"<<qry.lastError();
       }
        }
    

    .
    .

    • Otra forma:
        QSqlQuery admirar;
        admirar.prepare("SELECT*FROM otra WHERE id=:id");
        admirar.bindValue(":id", ui->lineEditBueno->text().trimmed());
        if(admirar.exec()){
    
            int fila=0;
    
            ui->tableWidgetMuestra->setRowCount(0);
    
            while(admirar.next()){
    
               ui->tableWidgetMuestra->insertColumn(0);
    
               ui->tableWidgetMuestra->insertRow(fila);
    
                ui->tableWidgetMuestra->setItem(0, 0, new QTableWidgetItem(admirar.value(1).toByteArray().constData()));
    
                ui->tableWidgetMuestra->setItem(0, 1, new QTableWidgetItem(admirar.value(2).toByteArray().constData()));
    
                ui->tableWidgetMuestra->setItem(0, 2, new QTableWidgetItem(admirar.value(3).toByteArray().constData()));
    
                ui->tableWidgetMuestra->setItem(0, 3, new QTableWidgetItem(admirar.value(4).toByteArray().constData()));
    
               fila++;
            }
    
             qDebug()<<"Los datos se han mostrado correctamente";
    
        } else {
            qDebug()<<"ERROR. Los datos no se hana mostrado correctamente";
            qDebug()<<"ERROR:"<<admirar.lastError();
        }
    
    • Y el error que me indica:
    Se ha conectado a la base de datos
    QSqlQuery::value: not positioned on a valid record
    QSqlQuery::value: not positioned on a valid record
    Los datos se han qry correctamente
    

    ¿Se te ocurre alguna manera de solucionarlo? Intento mantener el proyecto con QTableWidget en lugar de usar QTableView para no tener que montar otra vez el proyecto desde 0, pero si no queda más remedio tendré que optar por aprender otro método.

    La razón por la que necesito guardar en otra base de datos es porque según mi proyecto cada base de datos pertenece a una empresa diferente y lo que quiero es copiar unos datos concretos extraidos de una tabla de la bd1 a una tabla de la db2.

    Muchas gracias por responder.



  • Resuelto.
    Intenté muchas cosas para solucionar el problem, algunas incluian la utilización de next() que me faltaba en el código de mi respuesta anterior pero continuaba saliendo el error:

    QSqlQuery::value: not positioned on a valid record
    

    Al final creé un nuevo proyecto con una base de atos nuevas y funciona correctamente con este código:

        hospital=QSqlDatabase::addDatabase("QSQLITE");
        hospital.setDatabaseName("C:/Sqlite3/Hospital.sqlite");
    
        if(hospital.open()){
            qDebug()<<"4.Se ha conectado a la base de datos Hospital";
        }else{
            qDebug()<<"4.ERROR. No se ha conectado a la base de datos Hospital";
        }
    
        QSqlQuery mostrar;
        mostrar.prepare("SELECT*FROM Partes WHERE N_Parte=:ID");
        mostrar.bindValue(":ID",ui->lineEditN_Parte->text());
    
            if(mostrar.exec())
            {
                qDebug()<<"5.Los datos del parte se han mostrado correctamente";
            }else{
                qDebug()<<"5.ERROR. Los datos del parte no se han mostrado correctamente";
                qDebug()<<"5.ERROR:"<<mostrar.lastError();
            }
    
            mostrar.next();
    
            ui->tableWidget->setRowCount(15);
    
            QStringList Campos;
            Campos<<"Fecha de Emisión"<<"Unidad Hospitalaria";
    
                ui->tableWidget->setVerticalHeaderLabels(Campos);
    
                ui->tableWidget->insertColumn(0);
                ui->tableWidget->setColumnCount(1);
    
                ui->tableWidget->setItem(0, 0, new QTableWidgetItem(mostrar.value(1).toByteArray().constData()));
                ui->tableWidget->setItem(2, 0, new QTableWidgetItem(mostrar.value(2).toByteArray().constData()));
    

    Así que supongo que el problema estaba en la base de datos anterior, quizás en las columnas, quizás en las filas, quizás en los valores o quizás en el nombre de cada uno de estos elementos.
    Lo importante es que el código que adjunto en esta respuesta funciona correctamente, de modo que si alguien tiene un problema parecido espero que esto le ayude.

    Muchas gracias!



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.