Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QTableView



  • good afternoon with everyone, I have the following QDialog with a QTableView and a QLabel; then what I did was connect to a database, where I have saved images, these images, the information of these images I show them in rows in the QTableView and every time I select one of them the corresponding image is shown in the QLabel, until there everything is great; My question is how do I do the same when I go through each row of the QTableView, I mean when I use the keys up and down, because when I do that nothing is shown in the QLabel, I tried several things but it did not work, I hope you can help me is for a university project, I would appreciate any help, thanks in advance.

    I hope you have given me to understand.

    Note:
    I leave the source code here.

    the code of the main form.

    #ifndef PRINCIPALFRM_H
    #define PRINCIPALFRM_H
    
    #include <QDialog>
    #include <QSqlDatabase>
    #include <QFile>
    #include <QSqlTableModel>
    namespace Ui {
    class PrincipalFrm;
    }
    
    class PrincipalFrm : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit PrincipalFrm(QWidget *parent = nullptr);
        ~PrincipalFrm();
    
    private slots:
        void on_toolButton_clicked();
    
        void on_pushButton_clicked();
        void on_tableView_clicked(const QModelIndex &index);
        void on_pushButton_2_clicked();
    
    private:
        Ui::PrincipalFrm *ui;
        QSqlDatabase db;
        QFile file;
        QSqlTableModel *model;
    };
    
    #endif // PRINCIPALFRM_H
    

    here the .cpp

    #include "principalfrm.h"
    #include "ui_principalfrm.h"
    #include <QMessageBox>
    #include <QSqlError>
    #include <QFileInfo>
    #include <QFileDialog>
    #include <QSqlQuery>
    #include <QKeyEvent>
    PrincipalFrm::PrincipalFrm(QWidget *parent) :
        QDialog(parent),ui(new Ui::PrincipalFrm)
    {
        ui->setupUi(this);
        db=QSqlDatabase::addDatabase("QPSQL");
        if(!db.isDriverAvailable("QPSQL")){
            QMessageBox::critical(this,qApp->applicationName(),
                                  tr("Ocurrio un error al cargar el controlador.\n").append(
                                      db.lastError().text()));
            return;
        }
        db.setHostName("127.0.0.1");
        db.setPort(5432);
        db.setDatabaseName("dbimagenes");
        db.setUserName("postgres");
        db.setPassword("2311046");
        if(!db.open()){
            QMessageBox::critical(this,qApp->applicationName(),
                                  tr("Ocurrio un error al abrir la base de datos.\n").append(
                                      db.lastError().text()));
            return;
        }
        model=new QSqlTableModel(this);
    
        model->setTable("imagenes");
        model->select();
        model->setHeaderData(1,Qt::Horizontal,"Nombre imagen");
        model->setHeaderData(2,Qt::Horizontal,"Descripcion imagen");
        model->setHeaderData(3,Qt::Horizontal,"Imagen");
        ui->tableView->setModel(model);
    //    setWindowFlags(Qt::Dialog|Qt::MSWindowsFixedSizeDialogHint|
    //                   Qt::WindowMinimizeButtonHint|Qt::WindowCloseButtonHint);
        setWindowFlags(Qt::MSWindowsFixedSizeDialogHint);
    
        ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
        ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
        ui->tableView->hideColumn(0);
    
        if(model->rowCount()==0){
            ui->pushButton_2->setEnabled(false);
        }
        ui->pushButton->setDefault(true);
        ui->pushButton_2->setShortcut(QKeySequence(Qt::Key_Q));
        ui->toolButton->setShortcut(QKeySequence(Qt::Key_A));
    
        ui->tableView->setColumnWidth(2,120);
    }
    
    PrincipalFrm::~PrincipalFrm()
    {
        delete ui;
    }
    
    void PrincipalFrm::on_toolButton_clicked()
    {
        QString fileName=QFileDialog::getOpenFileName(this,"Abrir un aimagen",
                                     QDir::rootPath(),"Imagenes (*.png *.jpg *.jpeg)");
        file.setFileName(fileName);
        if(fileName.isEmpty()){
            return;
        }
        ui->lineEdit->setText(fileName);
        file.setFileName(fileName);
        QPixmap pixmap(fileName);
        ui->lblFoto->setPixmap(pixmap.scaled(ui->lblFoto->size()));
    
    }
    void PrincipalFrm::on_pushButton_clicked()
    {
        if(ui->lineEdit->text().isEmpty()||ui->lineEdit_2->text().isEmpty()){
            QMessageBox::critical(this,qApp->applicationName(),
                                  tr("Complete todos los campos."));
            ui->lineEdit_2->setFocus();
            return;
        }
        QFileInfo info(file);
        if(!file.open(QIODevice::ReadOnly)){
            return;
        }
        QByteArray imagen=file.readAll();
        QSqlQuery qry;
        qry.prepare("INSERT INTO imagenes(nombre,descripcion,img) VALUES(?,?,?)");
        qry.addBindValue(info.fileName(),QSql::In);
        qry.addBindValue(ui->lineEdit_2->text(),QSql::In);
        qry.addBindValue(imagen,QSql::In);
        if(!qry.exec()){
            QMessageBox::critical(this,qApp->applicationName(),
                                  tr("Error de ejecucion.\n").append(
                                      qry.lastError().text()));
            return;
        }
        QMessageBox::information(this,qApp->applicationName(),
                                 "Datos gusrdados!");
        ui->lineEdit->clear();
        ui->lineEdit_2->clear();
        ui->lblFoto->clear();
        model->select();
        file.close();
        if(model->rowCount()!=0){
            ui->pushButton_2->setEnabled(true);
        }
    
    }
    /**
    This is where I show the images in the QLabel, by clicking on a row of the QTableView,
    I want to do the same but when I slide through each row of the QTableView with the arrow keys,
    that is the question.
    **/
    void PrincipalFrm::on_tableView_clicked(const QModelIndex &index)
    {
        QSqlQuery qry;
        qry.prepare(("SELECT img FROM imagenes WHERE id_imagen=?"));
        qry.addBindValue(model->index(index.row(),0).data().toString());
        if(!qry.exec()){
            QMessageBox::critical(this,qApp->applicationName(),
                                  tr("Error de ejecucion.\n").append(
                                      qry.lastError().text()));
            return;
        }
        qry.next();
        QByteArray imagen=qry.value(0).toByteArray();
        QPixmap pixmap;
        pixmap.loadFromData(imagen);
        ui->lblFoto->setPixmap(pixmap.scaled(ui->lblFoto->size()));
    }
    
    void PrincipalFrm::on_pushButton_2_clicked()
    {
        QString nombre= model->index(ui->tableView->currentIndex().row(),1).data().toString();
       int res= QMessageBox::question(this,qApp->applicationName(),
                              QString("Seguro que quiere eliminar.").append("<h3>"+nombre+"</h3>"),
                                      QMessageBox::Yes|QMessageBox::No);
    
       if(res==QMessageBox::Yes){
           model->removeRow(ui->tableView->currentIndex().row());
           model->select();
           ui->tableView->selectRow(0);
       }
    
        if(model->rowCount()==0){
            ui->lblFoto->clear();
            ui->pushButton_2->setEnabled(false);
        }
        
    }
    

  • Lifetime Qt Champion



  • Some concrete example that you could provide, I say if it is possible.


  • Lifetime Qt Champion

    Just connect the signal with a slot in PrincipalFrm and do what you're doing in on_tableView_clicked()



  • Hi, you know I did what you said, but when I want to connect the currentChanged signal, it just does not appear, which is what I'm doing wrong.

    QObject::connect(ui->tableView, &QTableView::    ,this,[&](){
    
          QMessageBox::information(this,qApp->applicationName(),"Mensaje");
        });
    

  • Lifetime Qt Champion

    Hi,

    Do you mean there's no auto-completion ? If so, that shouldn't stop you, write the name of the signal. If you make any mistake in it, the compilation will fail.



  • the problem is not the auto completed, the problem is that the currentChanged () signal does not appear, when putting the four points, only one eslot appears and a function with the same name of the signal.


  • Lifetime Qt Champion

    Well, that sounds like the auto-complete feature malfunctioning. But again, that's just a helper. Write the signal name and go on with your application.



  • Well, what I can say is that I have not achieved anything yet, and the truth is that I'm tired of searching and not getting an answer, thanks anyway.


  • Lifetime Qt Champion

    @lincoln Did you try to write

    QObject::connect(ui->tableView, &QTableView::currentChanged, this,[&](){
    
          QMessageBox::information(this,qApp->applicationName(),"Mensaje");
        });
    

    ?
    There is nothing to search, you just need to write what was already suggested...



  • @jsulm said in QTableView:

    QMessageBox::information(this,qApp->applicationName(),"Mensaje");

    I already did that and when I do I get this error.
                                                 
    semmantic issue
    55:49: error 'currentChanged' is a protected member of 'QTableView'
    qtableview.h: 176: 10: note: declared protedted here

    note:

    I attached an image with the screenshot of the error that I get, thanks.![alt text](0_1552319875912_error.png image url)


  • Lifetime Qt Champion

    @Christian-Ehrlicher said in QTableView:

    QAbstractItemView::currentChanged()

    Ah, you have to go through the selectionModel, sorry

    connect(ui->tableView->selectionModel, &QItemSelectionModel::currentChanged, ...)



  • deluxe brother, thank you already solved my problem, greetings.


Log in to reply