Home > OS >  How to visualize a .txt or .csv file on a QTableView after triggering currentRowChanged(int currentR
How to visualize a .txt or .csv file on a QTableView after triggering currentRowChanged(int currentR

Time:09-08

Problem: How to visualize a .txt or .csv file on a QTableView after triggering currentRowChanged(int currentRow) on QListWidget?

I have a very simple interface that I designed as a minimal verifiable example that look like below with a QPushButton a QLineEdit a QListWidget and a QTableView.

If I upload a .csv file using the QPushButton there are no problem and the content of the file is correctly shown on a QTableView:

via push button

However, and here is the problem:

When I drag and drop (functionality correctly implemented) multiple files and I click on one of them I have problem visualizing the file because the content does not change. It seems that the slot currentRowChanged(int currentRow) in the QListWidget is never triggered despite the files exists.

enter image description here

Below is the desired result:

desired

Here is the example I implemented. If you copy/paste on your computer it will work no problem:

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.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QListWidgetItem>
#include <QStandardItemModel>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    enum fileFormat {
        CSV,
        TXT,
        OTHER
    };

    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void showFilesDetails(QListWidgetItem *item);
    void readFile(QString path, fileFormat format);
    void setValueAt(int ix, int jx, const QString &value);
protected:
    void dragEnterEvent(QDragEnterEvent *event);
    void dragLeaveEvent(QDragLeaveEvent *event);
    void dragMoveEvent(QDragMoveEvent *event);
    void dropEvent(QDropEvent *event);

private slots:
    void on_listWidget_currentRowChanged(int currentRow);
    void on_loadBtn_clicked();

private:
    Ui::MainWindow *ui;
    fileFormat *format;
    QStandardItemModel *model;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QDebug>
#include <QFileDialog>

namespace constants
{
const QStringList HEADERS = {
    "tax_id", "Org_name", "GeneID", "CurrentID", "Status"};
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setAcceptDrops(true);
    model = new QStandardItemModel(this);
    ui->tableView->setModel(model);
    model->setHorizontalHeaderLabels(constants::HEADERS);
    model->setColumnCount(constants::HEADERS.length());
    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);

    QHeaderView *horizontal = new QHeaderView(Qt::Horizontal, ui->tableView);
    horizontal->setSectionsClickable(true);
    horizontal->setHighlightSections(true);
    ui->tableView->setHorizontalHeader(horizontal);
}

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

void MainWindow::dragEnterEvent(QDragEnterEvent *event) { event->accept(); }
void MainWindow::dragLeaveEvent(QDragLeaveEvent *event) { event->accept(); }
void MainWindow::dragMoveEvent(QDragMoveEvent *event)   { event->accept(); }

void MainWindow::dropEvent(QDropEvent *event)
{
    QString name;
    QList<QUrl> urls;
    QList<QUrl>::Iterator i;
    urls = event->mimeData()->urls();
    for(i = urls.begin(); i != urls.end();   i) {
        name = i->path();
        ui->listWidget->addItem(name);
    }
}

void MainWindow::on_listWidget_currentRowChanged(int currentRow)
{
    QListWidgetItem *item = nullptr;
    if(ui->listWidget->count() > 0)
        ui->listWidget->setCurrentRow(currentRow);
    showFilesDetails(item);
}

void MainWindow::readFile(QString path, fileFormat format)
{
    QListWidgetItem *item = nullptr;
    QFile file(path);

    if(!file.exists()){
        qDebug() << "File does not exist "<<path;
    }else{
        qDebug() << path<< "File exist...";
    }
    if (file.fileName().endsWith(".txt", Qt::CaseInsensitive))
    {
        qDebug() << "File does not exist "<<file.fileName();
    } else if(file.fileName().endsWith(".csv", Qt::CaseInsensitive))
    {
        qDebug() << "File does not exist "<<file.fileName();
    }
    QString line;
    if (file.open(QIODevice::ReadOnly | QIODevice::Text)){
        QTextStream stream(&file);
        while (!stream.atEnd()){
            line = stream.readLine();
            ui->listWidget->setCurrentItem(item);
            qDebug() << "line: "<<line;
        }
    }
    file.close();
}

void MainWindow::showFilesDetails(QListWidgetItem *item)
{
    QString path;
    fileFormat frmt;
    readFile(path, frmt);
    ui->listWidget->setCurrentItem(item);
}

void MainWindow::on_loadBtn_clicked()
{
    auto filename = QFileDialog::getOpenFileName(this, "Open", QDir::rootPath(), "CSV file (*.csv)");
    if(filename.isEmpty()) {
        ui->statusbar->showMessage("File empty");
        return;
    }
    QFile file(filename);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        ui->statusbar->showMessage("File did not open");
        return;
    }
    QTextStream xin(&file);
    int ix = 0;
    while (!xin.atEnd()) {
        model->setRowCount(ix);
        auto line = xin.readLine();
        auto values = line.split(",");
        const int colCount = values.size();
        model->setColumnCount(colCount);
        for(int jx = 0; jx < colCount;   jx) {
            setValueAt(ix, jx, values.at(jx));
        }
          ix;
        ui->lineEdit->setText(filename);
        ui->statusbar->showMessage(filename);
    }
    ui->listWidget->addItem(filename);
    file.close();
}

void MainWindow::setValueAt(int ix, int jx, const QString &value)
{
    if (!model->item(ix, jx)) {
        model->setItem(ix, jx, new QStandardItem(value));
    } else {
        model->item(ix, jx)->setText(value);
    }
}

In order to solve the problem I read very useful sources and in particular I came across this one, this one and also I found this post useful. However, I am trying to figure out where the problem might be. The drag/drop functionality is properly implemented but how do I upload the files in the QTableView and properly trigger the QListWidget event? Thank to anyone who would have time to read and point to a potential solution.

CodePudding user response:

afaik,funtion on_listWidget_currentRowChanged triggered properly. function showFilesDetails passes an empty string to readFile,this may be the problem.

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDragMoveEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QDebug>
#include <QFileDialog>

namespace constants
{
const QStringList HEADERS = {
    "tax_id", "Org_name", "GeneID", "CurrentID", "Status"};
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setAcceptDrops(true);
    model = new QStandardItemModel(this);
    ui->tableView->setModel(model);
    model->setHorizontalHeaderLabels(constants::HEADERS);
    model->setColumnCount(constants::HEADERS.length());
    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::ResizeToContents);

    QHeaderView *horizontal = new QHeaderView(Qt::Horizontal, ui->tableView);
    horizontal->setSectionsClickable(true);
    horizontal->setHighlightSections(true);
    ui->tableView->setHorizontalHeader(horizontal);
}

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

void MainWindow::dragEnterEvent(QDragEnterEvent *event) { event->accept(); }
void MainWindow::dragLeaveEvent(QDragLeaveEvent *event) { event->accept(); }
void MainWindow::dragMoveEvent(QDragMoveEvent *event)   { event->accept(); }

void MainWindow::dropEvent(QDropEvent *event)
{
    QString name;
    QList<QUrl> urls;
    QList<QUrl>::Iterator i;
    urls = event->mimeData()->urls();
    for(i = urls.begin(); i != urls.end();   i) {
        name = i->toLocalFile();
        ui->listWidget->addItem(name);
    }
}

void MainWindow::on_listWidget_currentRowChanged(int currentRow)
{
    QListWidgetItem *item = nullptr;
    if(ui->listWidget->count() > 0)
        ui->listWidget->setCurrentRow(currentRow);
    showFilesDetails(item);
}

void MainWindow::readFile(QString path, fileFormat format)
{
    QListWidgetItem *item = nullptr;
    QFile file(path);

    if(!file.exists()){
        qDebug() << "File does not exist "<<path;
    }else{
        qDebug() << path<< "File exist...";
    }
    if (file.fileName().endsWith(".txt", Qt::CaseInsensitive))
    {
        qDebug() << "File does not exist "<<file.fileName();
    } else if(file.fileName().endsWith(".csv", Qt::CaseInsensitive))
    {
        qDebug() << "File does not exist "<<file.fileName();
    }file.open(QIODevice::ReadOnly | QIODevice::Text);
    QTextStream xin(&file);
    int ix = 0;
    while (!xin.atEnd()) {
        model->setRowCount(ix);
        auto line = xin.readLine();
        auto values = line.split(",");
        const int colCount = values.size();
        model->setColumnCount(colCount);
        for(int jx = 0; jx < colCount;   jx) {
            setValueAt(ix, jx, values.at(jx));
        }
          ix;
        ui->lineEdit->setText(path);
        ui->statusbar->showMessage(path);
    }
    file.close();
}

void MainWindow::showFilesDetails(QListWidgetItem *item)
{
    item=ui->listWidget->currentItem();
    QString path=
            item->data(Qt::DisplayRole).toString();;
    fileFormat frmt;
    readFile(path, frmt);
    ui->listWidget->setCurrentItem(item);
}

void MainWindow::on_loadBtn_clicked()
{
    auto filename = QFileDialog::getOpenFileName(this, "Open", QDir::rootPath(), "CSV file (*.csv)");
    if(filename.isEmpty()) {
        ui->statusbar->showMessage("File empty");
        return;
    }
    QFile file(filename);
    if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        ui->statusbar->showMessage("File did not open");
        return;
    }
    QTextStream xin(&file);
    int ix = 0;
    while (!xin.atEnd()) {
        model->setRowCount(ix);
        auto line = xin.readLine();
        auto values = line.split(",");
        const int colCount = values.size();
        model->setColumnCount(colCount);
        for(int jx = 0; jx < colCount;   jx) {
            setValueAt(ix, jx, values.at(jx));
        }
          ix;
        ui->lineEdit->setText(filename);
        ui->statusbar->showMessage(filename);
    }
    ui->listWidget->addItem(filename);
    file.close();
}

void MainWindow::setValueAt(int ix, int jx, const QString &value)
{
    if (!model->item(ix, jx)) {
        model->setItem(ix, jx, new QStandardItem(value));
    } else {
        model->item(ix, jx)->setText(value);
    }
}

  • Related