How to write data to mutiple QFiles - qt

I am trying to add a line to the file every time i receive data, and if the number of lines exceed 10 lines, create new files to store the data until create 5 files, but i encoutered a problem, that is the application will crash at the 56th line : QTextStream stream(current_record_file); , the code are :
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
simulateReceiveData();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::simulateReceiveData()
{
while(file_count < 5){
qDebug()<<"on recording ...";
if(file_count == 1 && msg_line_count == -1){
//create the very first new file
record_file_name_prefix = "D:/Project/MessageRecording";
QString record_file_name = record_file_name_prefix + "(1).asc";
qDebug()<<"record_file_name is"<<record_file_name;
QFile file(record_file_name);
if (!file.open(QFile::WriteOnly | QFile::Truncate)){
qDebug()<<QString("Fail to open file : %1").arg(record_file_name);
return;
}
//write the header
current_record_file = &file;
QTextStream stream(current_record_file);
stream << "START\r\n";
msg_line_count = 0;
}else if(msg_line_count == 10){
//write footer to privious file
QTextStream stream(current_record_file);
stream << "END";
stream.flush();
current_record_file->close();
//create next new file
file_count++;
QString record_file_name = record_file_name_prefix + QString("(%1).%2").arg(file_count).arg("asc");
QFile file(record_file_name);
if (!file.open(QFile::WriteOnly | QFile::Truncate))
return;
current_record_file = &file; //redirect to the new created file
msg_line_count = 0;
}else{
//write the main body
QTextStream stream(current_record_file); // CRASH HERE !
stream <<"0.0000 0 Rx 00 00 00 00 00 00 00 00\r\n";
msg_line_count++;
}
}
}
mainwindow.h :
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFile>
#include <QDateTime>
#include <QTextStream>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
void simulateReceiveData();
int file_count = 1;//number of files
int msg_line_count = -1;//number of lines in one file
QString record_file_name_prefix;
QFile* current_record_file = nullptr;//point to currently written file
};
#endif // MAINWINDOW_H

As stated by chehrlic's comment, you are accessing a (dangling) pointer to an object that has gone out-of-scope.
Two solutions exist:
Reopen the file on each write (may be incompatible with QFile::Truncate and less efficient)
Use QFile current_record_file as a member, instead of QFile* current_record_file. This seems to me the best approach.

Thanks for everyone's reply, i tried m7913d's second solution, and it can create multiple QFiles now ! The magic point is after you close last QFile current_record_file, and reset its file name by current_record_file.setFileName(record_file_name);, programm will help us create new file automatically. The new worrkable code are :
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QThread>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
simulateReceiveData();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::simulateReceiveData()
{
while(file_count < 5){
qDebug()<<"on recording ...";
if(file_count == 1 && msg_line_count == -1){
//create the very first new file
record_file_name_prefix = "D:/Project/MessageRecording";
QString record_file_name = record_file_name_prefix + QString::number(file_count) + ".asc";
current_record_file.setFileName(record_file_name);
if (!current_record_file.open(QFile::WriteOnly | QFile::Truncate)){
qDebug()<<QString("Fail to open file : %1").arg(record_file_name);
return;
}
//write the header
QTextStream stream(&current_record_file);
stream << "START\r\n";
msg_line_count = 0;
}else if(msg_line_count == 10){
//write footer to privious file
QTextStream stream(&current_record_file);
stream << "END";
stream.flush();
current_record_file.close();
file_count++;
QString record_file_name = record_file_name_prefix + QString::number(file_count) + ".asc";
qDebug()<<"new record file is"<<record_file_name;
current_record_file.setFileName(record_file_name);
if (!current_record_file.open(QFile::WriteOnly | QFile::Truncate)){
qDebug()<<QString("Fail to open file : %1").arg(record_file_name);
return;
}
QTextStream stream2(&current_record_file);
stream2 << "START\r\n";
msg_line_count = 0;
}else{
//write the main body
QTextStream stream(&current_record_file); // CRASH HERE !
stream <<file_count<<" 0.0000 0 Rx 00 00 00 00 00 00 00 00\r\n";
msg_line_count++;
QThread::sleep(1);
}
}
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QFile>
#include <QDateTime>
#include <QTextStream>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
void simulateReceiveData();
int file_count = 1;//number of files
int msg_line_count = -1;//number of lines in one file
QString record_file_name_prefix;
QFile current_record_file;
};
#endif // MAINWINDOW_H

Related

Problems not working QCanBus

Problems not create Can Bus Device, create project Qt 5.10 why not create ??
package serialbus be connected. CAN be connected across USB. IIts so hard. My life its harded. I'm a national minority, I'm not as clever as white masters, please do not grieve for me.
can bus Device not working
file.pro
QT += core gui serialbus
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = CAN_simple_experiment
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtSerialBus>
#include <QCanBus>
#include <QCanBusDevice>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
int i = 0;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
// Create device.
QCanBusDevice *device =
QCanBus::instance()>createDevice("socketcan","vcan0");
if (device != nullptr){
qDebug() << "Created device, state is:" << device->state();
ui->textEdit->append("Created device, state is:"+ device->state());
} else {
qFatal("Unable to create CAN device.");
ui->textEdit->append("Unable to create CAN device.");
}
//Connect.
if(device->connectDevice()){
qDebug() << "Connected, state is:" << device->state();
ui->textEdit->append("Connected, state is:"+ device->state());
} else {
qDebug() << "Connect failed, error is:" << device->errorString();
ui->textEdit->append("Connect failed, error is:"+ device->errorString());
}
}
You need first to check SocketCAN interfaces that can be used check documentation.
QString errorString;
const QList<QCanBusDeviceInfo> devices = QCanBus::instance()->availableDevices(
QStringLiteral("socketcan"), &errorString);
if (!errorString.isEmpty())
qDebug() << errorString;
You can't create the device if the list is empty (watch the errorString);
// Create device.
if (devices.count())
QCanBusDevice *device =
QCanBus::instance()>createDevice("socketcan","vcan0");
There is no support of socketcan on Windows.
There are Linux specific calls inside socketcanbackend.cpp:
#include <linux/can/error.h>
#include <linux/can/raw.h>
#include <linux/sockios.h>
...
if (Q_UNLIKELY(ioctl(canSocket, SIOCGSTAMP, &timeStamp) < 0)) {
...
etc

Get duration of QMediaPlaylist object

I create a player for audiobooks - when you open a folder with mp3 file, whole list of them is added to playlist and List View. And i have a Label, which suppose to show duration of the whole book. But player->duration returns only a duration of current track, and if i go through the loop and do playlist->next() every step, player->duration returns 0. I know about Phonon and file metadata, but i need to do this without using it.
I am attaching a source code of a working project, you can use. When the player changes the file, the duration is changed and printed out. To loop within files, there is a need to wait till the decoder completes reading the media file. See the code below and the comments.
This is mainwindow.cpp
#include "mainwindow.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
bool done =false;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
player = new QMediaPlayer(this);
playlist = new QMediaPlaylist(player);
playlist->setPlaybackMode(QMediaPlaylist::Sequential);
player->setPlaylist(playlist);
connect(player, &QMediaPlayer::durationChanged, this, &MainWindow::on_durationchanged);
//connect(player,&QMediaPlayer::)
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
playlist->addMedia(QUrl::fromLocalFile("Ar_today.mp3"));
playlist->addMedia(QUrl::fromLocalFile("Ar_sunday.mp3"));
playlist->setCurrentIndex(0); //set the first file
while (done == false) //wait till the duration is read
{
QApplication::processEvents();
}
done = false; playlist->setCurrentIndex(1); //change to the second file
while (done == false) //wait till the duration is read
{
QApplication::processEvents();
} //this way you can loop through files
player->setVolume(80);
player->play();
qDebug() << player->errorString();
}
void MainWindow::on_pushButton_2_clicked()
{
player->stop();
}
void MainWindow::on_durationchanged(qint64 duration)
{
done = true;
qDebug() << "duration = " << player->duration();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QDebug>
extern bool done;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_durationchanged(qint64 duration);
private:
Ui::MainWindow *ui;
QMediaPlayer* player;
QMediaPlaylist* playlist;
};
#endif // MAINWINDOW_H
In the form, create 2 buttons, one called pushbutton to play and the other is pushButton_2 to stop

Read multiple texts Qt

i am doing Qt project about displaying many texts. in detail, after 1st text display, it will close then display next file. My problem here was that just the last file displayed. all link resource paths are correct. Please help me fix me. Thanks in advance
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QString>
#include <QStackedWidget>
#include <QTextBrowser>
#include <QStringList>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStringList L;
L << ":/sample.txt" << ":/idp.txt";
foreach (QString str, L){
QFile file(str);
if (!file.open(QIODevice::ReadOnly))
QMessageBox::information(0,"error file path", file.errorString());
QString name = file.fileName();
QStringList parts = name.split("/");
QString lastBit = parts.at(parts.size()-1);
statusBar()->showMessage(lastBit);
QTextStream out(&file);
QString txt = out.readAll();
QStackedWidget *temp = new QStackedWidget();
QTextBrowser *textbrs = new QTextBrowser();
textbrs->setText(txt);
temp->addWidget(textbrs);
setCentralWidget(temp);
file.close();
}
}
MainWindow::~MainWindow()
{
delete ui;
}
Something like this:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QString>
#include <QStackedWidget>
#include <QTextBrowser>
#include <QStringList>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
L << ":/sample.txt" << ":/idp.txt"; //Class member of Type QStringList
textbrs = new QTextBrowser(); //Class member of Type QTextBrowser*
ui->centralWidget->layout()->addWidget(textbrs);
timer = new QTimer(); //Class member of Type QTimer*
timer->setInterval(5000);
connect(timer,SIGNAL(timeout()),this,SLOT(slotFileAction()));
timer->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::slotFileAction()
{
static int count = 0;
if(count >= L.size())
timer->stop();
QString str = L.at(count);
count++;
QFile file(str);
if (!file.open(QIODevice::ReadOnly))
QMessageBox::information(0,"error file path", file.errorString());
QString name = file.fileName();
QStringList parts = name.split("/");
QString lastBit = parts.at(parts.size()-1);
statusBar()->showMessage(lastBit);
QTextStream out(&file);
QString txt = out.readAll();
textbrs->setText(txt);
file.close();
}
Each time you will replace the old QStackedWidget by
setCentralWidget(temp);
The example to use QStackedWidget in Qt help document is following:
QWidget *firstPageWidget = new QWidget;
QWidget *secondPageWidget = new QWidget;
QWidget *thirdPageWidget = new QWidget;
QStackedWidget *stackedWidget = new QStackedWidget;
stackedWidget->addWidget(firstPageWidget);
stackedWidget->addWidget(secondPageWidget);
stackedWidget->addWidget(thirdPageWidget);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(stackedWidget);
setLayout(layout);
So, you should add multiple QTextBrowsers in QStackedWidget by addWidget() and use setCentralWiget() just once.
Hope helpful.

Windows Task Manager shows process memory keeps growing

I observed that through task mgr, the memory increases in steps of 4kB and 8kB, though not necessarily in this order.
Possible duplicate: Windows Task Manager shows process memory keeps growing even though there are no memory leaks
I am not sure whether this's occurring because I did not release the QTimer object, timer2. Please advise me how to stop this memory increase, and whether my guess of why it's occurring, is correct.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtCore>
#include <QDebug>
#include <QDateTime>
#include <QFileInfo>
#include <QString>
#include <opencv/cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#define TIMER2_VALUE 3000
#define UPDATED_IMAGE_STORAGE_PATH "E:\\QT1\\timeStampDateMod2\\TimeStampDateMod2\\updatedRefImg.JPG"
#define UPDATED_IMAGE_BACKUP_PATH "E:\\QT1\\timeStampDateMod2\\TimeStampDateMod2\\backUp\\updatedRefImg[%1].JPG"
using namespace std;
using namespace cv;
typedef struct
{
QDateTime dateTimeMod1;
QDateTime dateTimeMod2;
}tTimeMods;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QTimer *timer2;
tTimeMods findTimeModifiedStruct();
QDateTime findTimeModified();
void compareTimeMods(tTimeMods timeTypeFunction, QDateTime dateTimeMod2);
QString appendWithImageName(tTimeMods timeTypeFunction);
void shiftToRepository(QString pathString);
void updatedImgToRepository(QString pathString);
public slots:
void timerSlot2();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_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"
tTimeMods timeTypeFunction, timeTypeMain;
QDateTime dateTimeMod2;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
timeTypeMain = findTimeModifiedStruct();
timer2 = new QTimer(this);
connect(timer2, SIGNAL(timeout()), this, SLOT(timerSlot2()));
timer2->start(TIMER2_VALUE);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::timerSlot2()
{
dateTimeMod2 = findTimeModified();
compareTimeMods(timeTypeMain, dateTimeMod2);
//delete timer2;
}
//tTimeMods findTimeModifiedStruct()
tTimeMods MainWindow::findTimeModifiedStruct()
{
QString myFileName = UPDATED_IMAGE_STORAGE_PATH;
QFileInfo info(myFileName);
/*find last date modified*/
timeTypeFunction.dateTimeMod1 = info.lastModified();
timeTypeFunction.dateTimeMod2 = info.lastModified();
qDebug()<< "dateTimeMod1: " << timeTypeFunction.dateTimeMod1.toString() << endl << "dateTimeMod2: "<< timeTypeFunction.dateTimeMod2.toString();
return(timeTypeFunction);
}
QDateTime MainWindow::findTimeModified()
{
QString myFileName = UPDATED_IMAGE_STORAGE_PATH;
QFileInfo info(myFileName);
QDateTime dateTimeMod2 = info.lastModified();
qDebug()<< "dateTimeMod2: "<< dateTimeMod2.toString();
return(dateTimeMod2);
}
void MainWindow::compareTimeMods(tTimeMods timeTypeFunction, QDateTime dateTimeMod2)
{
if(dateTimeMod2 >= timeTypeFunction.dateTimeMod1)
{
timeTypeFunction.dateTimeMod1 = dateTimeMod2;
QString pathString = appendWithImageName(timeTypeFunction);
shiftToRepository(pathString);
}
}
QString MainWindow::appendWithImageName(tTimeMods timeTypeFunction)
{
/*appending just the timeMod with the path & image name*/
QString path = QString(UPDATED_IMAGE_BACKUP_PATH).arg(timeTypeFunction.dateTimeMod1.toString());
qDebug()<< "path: " << path;
return path;
}
void MainWindow::shiftToRepository(QString pathString)
{
updatedImgToRepository(pathString);
}
void MainWindow::updatedImgToRepository(QString pathString)
{
pathString.replace(":","-");
pathString.replace(1,1,":");
qDebug()<<"pathString now: "<<pathString;
/*convert QString into char* */
QByteArray pathByteArray = pathString.toLocal8Bit();
const char *path = pathByteArray.data();
IplImage *InputImg = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
InputImg = cvLoadImage(UPDATED_IMAGE_STORAGE_PATH ,CV_LOAD_IMAGE_UNCHANGED);
/*save the image*/
cvSaveImage(path,InputImg);
cvReleaseImage(&InputImg);
}
I'm not familiar with OpenCV, but it seems that these two lines cause you memory leak:
IplImage *InputImg = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
InputImg = cvLoadImage(UPDATED_IMAGE_STORAGE_PATH ,CV_LOAD_IMAGE_UNCHANGED);
In the first line you are creating an object, but in the second you are assigning another object to the pointer without releasing the previous one, so the previous one gets leaked.
Is creating an image even needed, while you are going to load it?

qt networkManager get

I want to download the url entered in the line edit widget.
I am not able to get it working , can some one please give me a short code snippet which can put the values of the file to a QString ?
void imdb::on_imdbGetButton_clicked()
{
Qstring link1 = ui->lineEdit2->text();
// QString link1 is the url to be downloaded.
}
I have added , the required header files..
Thanks..
I guess you're trying to download a file via http. Here's what you could do:
In you *.pro file add QT += network
Create an instance of QNetworkAccessManager class;
Supply your file URL to via QNetworkRequest object: manager->get(QNetworkRequest("file_url"));
Connect to the finished signal of the QNetworkAccessManager
In the finished signal handler read the content of the QNetworkReply and save it to the local file.
Below is a small example. Download will start in the button click of the MainForm class:
mainwindow.h:
#include <QMainWindow>
#include <QNetworkAccessManager>
#include <QDebug>
#include <QUrl>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QFile>
#include <QFileInfo>
#include <QPushButton>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QNetworkAccessManager* _manager;
private slots:
void on_pushButton_clicked();
void downloadFinished(QNetworkReply *reply);
};
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QPushButton* button = new QPushButton("Download", this);
button->setGeometry(20, 20, 80, 30);
connect(button, SIGNAL(clicked()), SLOT(on_pushButton_clicked()));
_manager = new QNetworkAccessManager(this);
connect(_manager, SIGNAL(finished(QNetworkReply*)), SLOT(downloadFinished(QNetworkReply*)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QUrl url("http://pics.mtii.com/ClassPictures2011/MIA/E110227-PMIA3-JEAN/thumbnails/P2270448%20copy.jpg");
_manager->get(QNetworkRequest(url));
}
void MainWindow::downloadFinished(QNetworkReply *reply)
{
QUrl url = reply->url();
if (reply->error())
{
qDebug() << "Download of " << url.toEncoded().constData()
<< " failed: " << reply->errorString();
}
else
{
QString path = url.path();
QString fileName = QFileInfo(path).fileName();
if (fileName.isEmpty()) fileName = "download";
QFile file(fileName);
if (file.open(QIODevice::WriteOnly))
{
file.write(reply->readAll());
file.close();
}
qDebug() << "Download of " << url.toEncoded().constData()
<< " succeded saved to: " << fileName;
}
}
hope this helps, regards

Resources