I have created a ui with QT designer.
In that ui i use one pushbutton for browse directories,and one lineedit for select dir path text to show, and another pushbuton for ok, these 3 widgets and one treewidget are placed on a groupbox horizontally.
What I would want to know is if i browse and click ok button then i want to display the treeview to that path on the ui
my test1.h file contains
#ifndef LINEEDIT_H
#define LINEEDIT_H
#include <QtGui>
#include "ui_line1.h"
#include <stdlib.h>
#include <iostream>
using namespace Ui;
class line : public QMainWindow
{
Q_OBJECT
public:
line(QWidget *parent = 0);
QTreeWidget(parent);
void viewer(QTreeWidgetItem* item,QString filePath);
private:
Ui::lineedit ui;
QDirModel *model;
public slots:
void browse();
void treeview();
void showDirectory(QTreeWidgetItem* item, int /*column*/);
};
#endif // LINEEDIT_H
my test1.cpp file contains
#include "test1.h"
#include <QTreeWidget>
#include <QtGui>
#include <stdlib.h>
#include <iostream>
#include<QWidget>
#include<QTreeWidgetItem>
line::line(QWidget* parent)
{
ui.setupUi(this);
connect(ui.browse, SIGNAL(clicked()), this,SLOT(browse()));
connect(ui.ok, SIGNAL(clicked()), this,SLOT(treeview()));
connect(this , SIGNAL(itemClicked(QTreeWidgetItem*,int)),this,SLOT(showDirectory(QTreeWidgetItem*,int)));
}
void line::browse()
{
QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
"/home",QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
ui.lineEdit->setText(dir);
}
void line::treeview()
{
QWidget *centralWidget = new QWidget();
line *tree = new line (centralWidget);
tree->setFixedSize(395,395);
QTreeWidgetItem* headerItem = new QTreeWidgetItem();
headerItem->setText(0,QString("File Name"));
headerItem->setText(1,QString("Size (Bytes)"));
headerItem->setText(2,QString("Path"));
ui.treeWidget->setHeaderItem(headerItem);
ui.treeWidget->setColumnCount(2);
//ui.treeView->
//setHeaderItem(headerItem);
QString strdir=ui.lineEdit->text();
QDir* rootDir = new QDir(strdir);
QFileInfoList filesList = rootDir->entryInfoList();
foreach(QFileInfo fileInfo, filesList)
{
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setText(0,fileInfo.fileName());
if(fileInfo.isFile())
{
item->setText(1,QString::number(fileInfo.size()));
item->setIcon(0,*(new QIcon("file.jpg")));
}
if(fileInfo.isDir())
{
item->setIcon(0,*(new QIcon("folder.jpg")));
viewer(item,fileInfo.filePath());
}
item->setText(2,fileInfo.filePath());
ui.treeWidget->addTopLevelItem(item);
}
QPalette* palette = new QPalette();
palette->setColor(QPalette::Base,Qt::red);
ui.treeWidget->setPalette(*(palette));
/*window->setCentralWidget(centralWidget);*/
/*ui.treeWidget->addTopLevelItem(centralWidget);*/
/*window->show();*/
return treeview();
}
void line::viewer(QTreeWidgetItem* item,QString filePath)
{
QDir* rootDir = new QDir(filePath);
QFileInfoList filesList = rootDir->entryInfoList();
foreach(QFileInfo fileInfo, filesList)
{
QTreeWidgetItem* child = new QTreeWidgetItem();
child->setText(0,fileInfo.fileName());
if(fileInfo.isFile())
{
child->setText(1,QString::number(fileInfo.size()));
}
if(fileInfo.isDir())
{
child->setIcon(0,*(new QIcon("folder.jpg")));
child->setText(2,fileInfo.filePath());
}
item->addChild(child);
}
}
void line::showDirectory(QTreeWidgetItem* item, int )
{
QDir* rootDir = new QDir(item->text(2));
QFileInfoList filesList = rootDir->entryInfoList();
foreach(QFileInfo fileInfo, filesList)
{
QTreeWidgetItem* child = new QTreeWidgetItem();
child->setText(0,fileInfo.fileName());
if(fileInfo.isFile())
{
child->setText(1,QString::number(fileInfo.size()));
child->setIcon(0,*(new QIcon("file.jpg")));
}
if(fileInfo.isDir())
{
child->setIcon(0,*(new QIcon("folder.jpg")));
child->setText(2,fileInfo.filePath());
}
item->addChild(child);
/*resizeColumnToContents(0);*/
}
}
main.cpp contains
#include "test1.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
line w;
w.show();
return a.exec();
}
am not getting output, while am checking on the debug points each and every thing fine but not getting the output on the ui treewidget
Is this possible, please help me where can i modify my code.
Thanks all.
test1.cppfile:
#include "test1.h"
#include <QTreeWidget>
#include <QtGui>
#include <stdlib.h>
#include <iostream>
#include<QWidget>
#include<QTreeWidgetItem>
line::line(QWidget* parent)
{
ui.setupUi(this);
connect(ui.browse, SIGNAL(clicked()), this,SLOT(browse()));
connect(ui.ok, SIGNAL(clicked()), this,SLOT(treeview()));
connect(this , SIGNAL(itemClicked(QTreeWidgetItem*,int)),this,SLOT(showDirectory(QTreeWidgetItem*,int)));
}
void line::browse()
{
QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
"/home",QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
ui.lineEdit->setText(dir);
}
void line::treeview()
{
QString strdir=ui.lineEdit->text();
QDir* rootDir = new QDir(strdir);
QFileInfoList filesList = rootDir->entryInfoList();
/*QTreeWidgetItem* item = new QTreeWidgetItem();*/
ui.treeWidget->setColumnCount(1);
QList<QTreeWidgetItem *> items;
foreach(QFileInfo fileInfo, filesList)
{
QTreeWidgetItem* item = new QTreeWidgetItem();
item->setText(0,fileInfo.fileName());
if(fileInfo.isFile())
{
item->setText(1,QString::number(fileInfo.size()));
item->setIcon(0,*(new QIcon("file.jpg")));
/*treeItem->setCurrentItem(item);*/
}
if(fileInfo.isDir())
{
item->setIcon(0,*(new QIcon("folder.jpg")));
viewer(item,fileInfo.filePath());
}
item->setText(2,fileInfo.filePath());
ui.treeWidget->addTopLevelItem(item);
/* ui.treeWidget->insertTopLevelItems(0, item);*/
items.append(new QTreeWidgetItem((QTreeWidget*)0, QStringList(QString("item: %1"))));
ui.treeWidget->insertTopLevelItems(0, items);
}
}
void line::viewer(QTreeWidgetItem* item,QString filePath)
{
QDir* rootDir = new QDir(filePath);
QFileInfoList filesList = rootDir->entryInfoList();
foreach(QFileInfo fileInfo, filesList)
{
QTreeWidgetItem* child = new QTreeWidgetItem();
child->setText(0,fileInfo.fileName());
if(fileInfo.isFile())
{
child->setText(1,QString::number(fileInfo.size()));
}
if(fileInfo.isDir())
{
child->setIcon(0,*(new QIcon("folder.jpg")));
child->setText(2,fileInfo.filePath());
}
item->addChild(child);
ui.treeWidget->addTopLevelItem(item);
}
}
void line::showDirectory(QTreeWidgetItem* item, int )
{
QDir* rootDir = new QDir(item->text(2));
QFileInfoList filesList = rootDir->entryInfoList();
foreach(QFileInfo fileInfo, filesList)
{
QTreeWidgetItem* child = new QTreeWidgetItem();
child->setText(0,fileInfo.fileName());
if(fileInfo.isFile())
{
child->setText(1,QString::number(fileInfo.size()));
child->setIcon(0,*(new QIcon("file.jpg")));
}
if(fileInfo.isDir())
{
child->setIcon(0,*(new QIcon("folder.jpg")));
child->setText(2,fileInfo.filePath());
}
item->addChild(child);
ui.treeWidget->addTopLevelItem(item);
/*resizeColumnToContents(0);*/
}
}
test1.h file:
#ifndef LINEEDIT_H
#define LINEEDIT_H
#include <QtGui>
#include "ui_line1.h"
#include <stdlib.h>
#include <iostream>
using namespace Ui;
class line : public QMainWindow
{
Q_OBJECT
public:
line(QWidget *parent = 0);
QTreeWidget(parent);
void viewer(QTreeWidgetItem* item,QString filePath);
private:
Ui::lineedit ui;
QDirModel *model;
public slots:
void browse();
void treeview();
void showDirectory(QTreeWidgetItem* item, int /*column*/);
};
#endif // LINEEDIT_H
main.cpp file:
#include "test1.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
line w;
w.show();
return a.exec();
}
Related
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:
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.
Below is the desired result:
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.
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);
}
}
In an earlier Question I asked about why my program/QTcpServer was crashing all the time, and I really appreciate the help I got from everyone.
However, I have decided to try and rebuild the Program from scratch in order to see why it crashes, and I may have found something.
Allow me to post the new Code below:
//mainwindow.h
#include <QMainWindow>
#include <QPushButton>
#include <QTextEdit>
#include <QStandardItemModel>
#include <QTcpServer>
#include <QTcpSocket>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void startServer();
void handleConnection();
void readMessage();
void ReadXML(QString XMLString);
private:
QPushButton *SServer;
QTextEdit * ContainerView; //not changing to QTableView just yet
int Pallet_Number;
QTcpServer *tcpServer;
QTcpSocket *tcpSocket;
};
//mainwindow.cpp
#include "mainwindow.h"
#include <QLabel>
#include <QLayout>
#include <QDebug>
#include <QDomDocument>
#include <QRegularExpression>
static QRegularExpression Box_Code("B");
static QRegularExpression Cylinder_Code("C");
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
SServer(new QPushButton("Start Listening")),
ContainerView(new /*QTableView*/QTextEdit),
tcpServer(new QTcpServer),
tcpSocket(new QTcpSocket)
{
QStringList HeaderRow;
HeaderRow.append("Pallet");
HeaderRow.append("Container");
HeaderRow.append("Code");
HeaderRow.append("Height");
HeaderRow.append("Breadth/Diameter");
HeaderRow.append("Length");
HeaderRow.append("Weight");
resize(800,300);
connect(SServer, &QPushButton::clicked, this, &MainWindow::startServer);
connect(tcpServer, &QTcpServer::newConnection, this, &MainWindow::handleConnection);
connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::handleConnection);
QLabel *Lab1(new QLabel("Listening on Port 6164"));
QHBoxLayout *HB(new QHBoxLayout);
QVBoxLayout *VB(new QVBoxLayout);
HB->addWidget(SServer);
HB->addWidget(Lab1);
VB->addItem(HB);
VB->addWidget(ContainerView);
QWidget *window(new QWidget);
window->setLayout(VB);
setCentralWidget(window);
}
MainWindow::~MainWindow()
{
}
void MainWindow::startServer()
{
if(!tcpServer->listen(QHostAddress::LocalHost, 6164)){
qDebug() << "Error connecting to Server";
tcpServer->close();
return;
} else {
qDebug() << "Started Successfully";
}
}
void MainWindow::handleConnection()
{
tcpSocket = tcpServer->nextPendingConnection();
qDebug() << "New Connection!";
connect(tcpSocket, &QTcpSocket::readyRead, this, &MainWindow::readMessage);
}
void MainWindow::readMessage()
{
ContainerView->clear(); //clear table to prepare for new XMLString
QByteArray buffer = tcpSocket->readAll();
QString FromContainer = QString::fromUtf8(buffer);
ReadXML(FromContainer);
}
void MainWindow::ReadXML(QString XMLString)
{
ContainerView->append(XMLString);
QDomDocument Xml_String;
Xml_String.setContent(XMLString);
QDomElement Xml_Root = Xml_String.documentElement();
if(Xml_Root.tagName() == "Pallets")
{
QDomElement Xml_Pallet = Xml_Root.firstChildElement();
while(!Xml_Pallet.isNull())
{
if(Xml_Pallet.tagName() == "Pallet")
{
int PN = Xml_Pallet.attribute("Number").toInt(nullptr,10);
QDomElement Box_Cyl = Xml_Pallet.firstChildElement();
while(!Box_Cyl.isNull())
{
if(Box_Cyl.tagName() == "Box")
{
QString BC = Box_Cyl.tagName();
ContainerView->append("Pallet No. " + QString::number(PN) + "\nContainer: " + BC);
// QDomElement Box_Info = Box_Cyl.firstChildElement();
// while(!Box_Info.isNull())
// {
// ...more code
// Box_Info = Box_Info.nextSiblingElement();
// }
} else if(Box_Cyl.tagName() == "Cylinder")
{
QString BC = Box_Cyl.tagName();
ContainerView->append("Pallet No. " + QString::number(PN) + "\nContainer: " + BC);
}
Box_Cyl = Box_Cyl.nextSiblingElement();
}
}
Xml_Pallet = Xml_Pallet.nextSiblingElement();
}
}
}
The XML String I am trying to read is shown below:
When I include the commented code to read the Elements within 'Box' or 'Cylinder' (I altered the code to check both sides), the program freezes.
This hasn't happened to me before, so I have no idea what to do.
Having a problem with main window crashing on close, but only if I open the window normal size (not filling the screen) and then maximize it and close the window. If I open it normal size and close it, no problem. This project includes a tableview, tableModel and a ProxyModel. While debugging, it seems to be crashing on this statement in the proxy model header function:
return sourceModel()->headerData(section, orientation, role);
I'm assuming I am missing something in my main constructor based on what I've researched, but I'm not seeing it.
Main Window:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QString>
#include "XMLFile.h"
#include "XMLReader.h"
#include "XMLWriter.h"
#include <QFile>
#include <QMainWindow>
#include <QTableWidget>
#include <QStringList>
#include <QHeaderView>
#include <QAction>
#include <QStandardItemModel>
#include <QTableView>
#include <QSortFilterProxyModel>
#include "TableModel.h"
#include "ProxyModel.h"
#include <QItemSelectionModel>
#include "CustomTableView.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
QWidget *centralWidget;
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
const QString filename;
public slots:
void ReceiveMessage( const QString &message );
signals:
void readXmlFile( const QString &fileName );
void getXmlTableData();
void setFilter( QString );
private slots:
void on_actionOpen_triggered();
void on_actionFind_triggered();
void on_pushButton_clicked();
void on_tableView_activated(const QModelIndex &index);
void on_actionExport_XML_triggered();
void on_actionExit_triggered();
private:
Ui::MainWindow *ui;
QString xmlFileName;
QFile file;
XMLReader xmlReader;
XMLWriter xmlWriter;
QVector<QString> xmlArray;
QString filter = "";
CustomTableView *tableView;
TableModel mTableModel;
ProxyModel* proxyModel;
QString accountValue;
QString deptValue;
QString yearValue;
QString filterText;
void createItems();
void createConnections();
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QString>
#include <QDebug>
#include <QMessageBox>
#include <QFile>
#include <QFileDialog>
#include <QApplication>
#include "XMLReader.h"
#include "XMLWriter.h"
#include "XMLFile.h"
#include <QInputDialog>
#include <QMenu>
#include <QModelIndexList>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, xmlReader( filename )
, xmlWriter( filename, &mTableModel )
//, tableView( NULL )
//, proxyModel( NULL )
//, m_xmlView(NULL)
{
ui->setupUi(this);
connect(&xmlReader, SIGNAL(SendMessage(const QString)), this, SLOT(ReceiveMessage(const QString)));
/* Setup tableview */
tableView = new CustomTableView(this);
ui->verticalLayout->addWidget(tableView);
tableView->setSortingEnabled(true);
/* Table Model Setup */
proxyModel = new ProxyModel(this);
proxyModel->setSourceModel(&mTableModel);
createConnections();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::ReceiveMessage(const QString &message)
{
QMessageBox::warning(this, "Warning", "Cannot open file : " + message);
}
void MainWindow::on_actionOpen_triggered()
{
QString filename = QFileDialog::getOpenFileName((this),"Open file");
xmlReader.readFile(filename);
setWindowTitle(filename);
createItems();
}
void MainWindow::createItems()
{
xmlArray = xmlReader.getXmlData();
int tableSize = xmlArray.size();
QStringList strList;
QString strSplit = "";
QVector<TableItem> rows;
/* Split into individual items, add as row to tableItem array.*/
/* Insert each tableItem array into the table model. */
for( int row = 0; row < tableSize; row++ )
{
TableItem newRow;
strSplit = xmlArray[row];
strList = strSplit.split("|");
for( int k = 0; k < strList.length(); k++)
{
newRow.setData(k, strList[k] );
}
rows << newRow;
}
mTableModel.initModel( rows );
QAbstractItemModel* model = nullptr;
model = proxyModel;
tableView->setModel( model );
tableView->setColumnHidden(0, true);
}
void MainWindow::createConnections()
{
QObject::connect(ui->lineEdit, SIGNAL(textChanged(QString)), proxyModel, SLOT(setAccount(QString)));
QObject::connect(ui->lineEdit_2, SIGNAL(textChanged(QString)), proxyModel, SLOT(setDept(QString)));
QObject::connect(ui->lineEdit_3, SIGNAL(textChanged(QString)), proxyModel, SLOT(setYear(QString)));
QObject::connect(this, SIGNAL(setFilter(QString)), proxyModel, SLOT(setSearchFilter(QString)));
}
void MainWindow::on_actionFind_triggered()
{
/* Open find string dialog */
bool ok;
QString filterText = QInputDialog::getText(this, tr("Find"),
tr("Search for string:"), QLineEdit::Normal,"", &ok);
setFilter( filterText );
}
void MainWindow::on_pushButton_clicked()
{
/* Clear filter values */
ui->lineEdit->setText("");
ui->lineEdit_2->setText("");
ui->lineEdit_3->setText("");
setFilter("");
}
void MainWindow::on_tableView_activated(const QModelIndex &index)
{
}
void MainWindow::on_actionExport_XML_triggered()
{
/* Open save file dialog, call xmlWriter */
QString filename = QFileDialog::getSaveFileName(this, tr("Save XML File"), ".", tr("XML files (*.xml)"));
xmlWriter.WriteFile(filename);
}
void MainWindow::on_actionExit_triggered()
{
QApplication::quit();
}
WORKING CODE: MainWindow.cpp
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, xmlReader( filename )
{
ui->setupUi(this);
connect(&xmlReader, SIGNAL(SendMessage(const QString)), this, SLOT(ReceiveMessage(const QString)));
/* Setup tableview */
tableView = new CustomTableView(this);
ui->verticalLayout->addWidget(tableView);
tableView->setSortingEnabled(true);
/* Table Model Setup */
proxyModel = new ProxyModel(this);
proxyModel->setSourceModel(&mTableModel);
createConnections();
}
MainWindow::~MainWindow()
{
delete proxyModel; /* Newly added */
delete tableView; /* Newly added */
delete ui;
}
I can upload more source code if needed. Thanks for any insight here.
-d
What works so far: opening a textfile via QFileDialog and showing the contents of the textfile in a Qlabel(showfile).
I too have a for-loop that counts how many \n are in the textfile.
Now what I want is that line after line in the textfile is assigned to a new Qlabel meaning each Qlabel contains one line of the textfile and place it dynamically on runtime.
Maybe you can help since I´m a little stuck here.
Here´s my qwidget class where the labels should be placed:
class mywidget:public QWidget //class for displaying everything
{
Q_OBJECT
private:
QGridLayout *area;
QLabel *showfile; //shows input from textfile
QLabel *processname,*status; //captionlabel
QFont *pfont,*sfont; //fontoption for processname&status
QLabel **processes; //2D array to dynamically create QLabels for each entry in file
public:
mywidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = 0):QWidget(parent,flags)
{
this->area = new QGridLayout(this);
this->showfile = new QLabel(tr("Test"),this);
this->pfont = new QFont();
this->pfont->setPixelSize(20);
this->sfont = new QFont();
this->sfont->setPixelSize(20);
this->processname = new QLabel(tr("Process_Name:"),this);
this->processname->setFont(*pfont);
this->status = new QLabel(tr("Status:"),this);
this->status->setFont(*sfont);
this->area->addWidget(this->processname,0,0,Qt::AlignHCenter);
this->area->addWidget(this->status,0,1,Qt::AlignHCenter);
this->area->addWidget(this->showfile,1,0,Qt::AlignHCenter);
this->area->setSpacing(10);
}
~mywidget()
{
delete this->area;
delete this->showfile;
delete this->pfont;
delete this->sfont;
delete this->processname;
delete this->status;
}
friend class mywindow;
};
And here is my open-method from QMainwindow class:
void mywindow::oeffnen()
{
this->openfilename = QFileDialog::getOpenFileName //open textfile dialog
(this,
tr("Datei öffnen"),
QDir::homePath(),
"Textdateien (*.txt *.docx *.doc);;" "Alle Dateien (*.*)"
);
if(!this->openfilename.isEmpty())
{
this->file = new QFile(this->openfilename);
this->file->open(QIODevice::ReadOnly);
this->stream = new QTextStream(this->file);
this->fileread = this->stream->readAll();
for(int z = 0;z<this->fileread.length();++z) //check entries in string by counting \n
{
this->eintraege = this->fileread.count(QRegExp("\n"));
}
//this->s_eintraege = QString::number(this->eintraege); //converting to string for displaying
this->central->showfile->setText(this->fileread); //assign filecontent to label
if(!this->file->isReadable())
{
QMessageBox::information(this,
tr("Fehler"),
tr("Konnte Datei %1 nicht laden!").arg(this->openfilename)
);
}
else
{
QMessageBox::information(this,
tr("OK"),
tr("Konnte Datei %1 laden!").arg(this->openfilename)
);
}
this->file->close();
}
}
You can add a new QLabel into a layout for each new line you read from a file. You can store the labels in a container like QVector so you can access their text later on. Here is an example:
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QFile>
#include <QLayout>
#include <QTextStream>
#include <QDebug>
class DisplayWidget : public QWidget
{
Q_OBJECT
public:
DisplayWidget(QWidget *parent = 0) : QWidget(parent)
{
labelLayout = new QVBoxLayout;
setLayout(labelLayout);
resize(200, 200);
}
void addLabel(const QString &text)
{
QLabel *label = new QLabel(text);
label_vector.append(label);
labelLayout->addWidget(label);
}
void readFile(const QString &filename)
{
QFile file(filename);
if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QTextStream ts(&file);
while(!ts.atEnd())
{
QString line = ts.readLine();
if(!line.isEmpty())
addLabel(line);
}
}
QString getLabelText(int index)
{
if(label_vector.size() > index)
return label_vector[index]->text();
return QString();
}
private:
QVBoxLayout *labelLayout;
QVector<QLabel*> label_vector;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
DisplayWidget w;
w.readFile("somefile.txt");
w.show();
qDebug() << w.getLabelText(3);
return a.exec();
}
#include "main.moc"
So, after I make my QJsonModel, load the data, and set the treeView model, it will load the data normally into the treeView. Although, when I do this after a network request has been finished (serviceRequestFinished(QNetworkReply* reply)), it just doesn't woek. I can qDebug the Json data that is passed, but when it comes down to the Json loading and the model setting. It just fails to finish. Also, for some reason it won't set the Json from the network request, but if I just set it to set the json from a separate button, the json get added successfully. So that means that the Json is formatted correctly. The QJsonModel & QJsonItem are external classes not provided with Qt, that located here.
Here is my code:
Mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QModelIndex>
#include <QItemSelection>
#include <QFile>
#include <QFileInfo>
#include <QList>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
#include <QStringList>
#include <QTimer>
#include <QUrl>
#include <QTreeWidgetItem>
#include <QJsonDocument>
#include <QJsonObject>
#include "qjsonmodel.h"
#include <QClipboard>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
void setJson(QString json);
void getPlaylistList(QString accessToken);
QString disableStreams();
void appendEditValues(int currentRow);
void addVectorItems();
void streamCheck();
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_radioButtonNoStream_clicked()
{
streamCheck();
}
void on_radioButtonTwitchStream_clicked()
{
streamCheck();
}
void on_radioButtonYTStream_clicked()
{
streamCheck();
}
void on_pushButtonAddVid_clicked();
void on_pushButtonApplyAddVid_clicked();
void on_pushButtonDeleteSelection_clicked();
void on_pushButtonApplyAll_clicked();
public slots:
void serviceRequestFinished(QNetworkReply* reply);
void connectAPI(QString code);
signals:
void authenticate(QString accessCode);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "authdialog.h"
#include <qDebug>
#include <QVector>
#include <QMessageBox>
#include <QStandardItemModel>
#include <QFile>
#include <QUrlQuery>
int val = 0;
int selected;
QVector<QString> vidTitles;
QVector<QString> vidUrls;
QVector<int> vidNumber;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
streamCheck();
ui->groupBoxEditVideo->setEnabled(false);
connect(this, SIGNAL(authenticate(QString)), SLOT(connectAPI(QString)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::streamCheck()
{
if (ui->radioButtonNoStream->isChecked())
{
ui->groupBoxStreamSetup->setEnabled(false);
ui->groupBoxStreamSetup->setTitle("No Stream Selected!");
}
else if (ui->radioButtonTwitchStream->isChecked())
{
ui->groupBoxStreamSetup->setEnabled(true);
ui->groupBoxStreamSetup->setTitle("Twitch Setup");
}
else if (ui->radioButtonYTStream->isChecked())
{
ui->groupBoxStreamSetup->setEnabled(true);
ui->groupBoxStreamSetup->setTitle("YouTube Stream Setup");
}
}
void MainWindow::on_pushButtonAddVid_clicked()
{
AuthDialog *auth = new AuthDialog(this);
auth->setModal(true);
auth->exec();
delete auth;
}
void MainWindow::setJson(QString json)
{
qDebug() << json;
QJsonModel * model = new QJsonModel;
model->loadJson(json.toUtf8());
ui->treeView->setModel(model);
delete model;
}
void MainWindow::getPlaylistList(QString accessToken)
{
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*)));
//
QNetworkRequest request(QUrl("https://www.googleapis.com/youtube/v3/search?part=snippet&forMine=true&order=viewCount&type=video&access_token=" + accessToken));
networkManager->get(request);
}
QString MainWindow::disableStreams()
{
QString line = "";
QString test = "";
QFile file;
file.setFileName("C:/WampStack/apache2/htdocs/index.html");
file.open(QIODevice::ReadWrite);
QTextStream in(&file);
while(!in.atEnd())
{
line += in.readAll();
}
if (line.contains("<!--t-->") && !line.contains("<!--y-->"))
{
//Twitch Stream is on, must turn it off
test = line.replace("<!--t-->", "<!--t");
test = test.replace("><!--tt-->", ">tt-->");
return test;
}
else if (line.contains("<!--y-->") && !line.contains("<!--t-->"))
{
//YouTube Stream is on, must turn it off
test = line.replace("<!--y-->", "<!--y");
test = test.replace("><!--yy-->", ">yy-->");
return test;
}
else if (line.contains("<!--y-->") && line.contains("<!--t-->"))
{
test = line.replace("<!--y-->", "<!--y");
test = test.replace("><!--yy-->", ">yy-->");
test = test.replace("<!--t-->", "<!--t");
test = test.replace("><!--tt-->", ">tt-->");
return test;
}
else
{
return line;
}
file.close();
return line;
}
void MainWindow::connectAPI(QString code)
{
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*)));
QUrlQuery postData;
postData.addQueryItem("code", code);
postData.addQueryItem("client_id", "CLIENT-ID");
postData.addQueryItem("client_secret", "CLIENT-SECRET");
postData.addQueryItem("redirect_uri", "REDIRECT-URI");
postData.addQueryItem("grant_type", "authorization_code");
QNetworkRequest request(QUrl("https://accounts.google.com/o/oauth2/token"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
networkManager->post(request, postData.toString(QUrl::FullyEncoded).toUtf8());
}
void MainWindow::appendEditValues(int currentRow)
{
}
void MainWindow::addVectorItems()
{
}
void MainWindow::on_pushButtonApplyAddVid_clicked()
{
}
void MainWindow::on_pushButtonDeleteSelection_clicked()
{
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "Are you sure?", "Do you want to permanently delete this entry?", QMessageBox::Yes|QMessageBox::No);
if (reply == QMessageBox::Yes)
{
}
addVectorItems();
}
void MainWindow::on_pushButtonApplyAll_clicked()
{
QString line = disableStreams();
QFile::remove("C:/WampStack/apache2/htdocs/index.html");
QFile file;
file.setFileName("C:/WampStack/apache2/htdocs/index.html");
file.open(QIODevice::ReadWrite);
//Start code for streaming
if (ui->radioButtonTwitchStream->isChecked() && line.contains("<!--t") && line.contains(">tt-->") && !line.contains("<!--t-->") && !line.contains("<!--tt-->"))
{
QString test = line.replace("<!--t", "<!--t-->");
test = line.replace(">tt-->", "><!--tt-->");
QTextStream stream( &file );
stream << test;
}
else if (ui->radioButtonYTStream->isChecked() && line.contains("<!--y") && line.contains(">yy-->") && !line.contains("<!--y-->") && !line.contains("<!--yy-->"))
{
QString test = line.replace("<!--y", "<!--y-->");
test = test.replace(">yy-->", "><!--yy-->");
QTextStream stream( &file );
stream << test;
}
else if (ui->radioButtonNoStream->isChecked())
{
QTextStream stream(&file);
stream << line;
}
//End code for streaming
file.close();
}
void MainWindow::serviceRequestFinished(QNetworkReply* reply)
{
QByteArray json = reply->readAll();
QString output = QString::fromUtf8(json);
QJsonDocument settdoc = QJsonDocument::fromJson(output.toUtf8());
QJsonObject sett2 = settdoc.object();
if (val == 0)
{
val++;
getPlaylistList(sett2.value(QString("access_token")).toString());
}
else if (val == 1)
{
setJson(output.toUtf8());
}
}
Main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
QJsonModel only works if the the JSON's root element is an object (see the bug report on github.com). I guess your JSON's root is an array.