How to convert unsigned long long value to a string in qt - qt

I have a calulation that returns large value of factorials of a given number (ex: Factorial of 22 = 17196083355034583040). I want to set the result to a label. I did as shown below.
void Dialog::onNumberChanged(unsigned long long Number)
{
ui->resultPrime->setText(QString::number(Number));
}
MyThread.h
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = 0);
void run();
bool Stop;
int inputNumber;
unsigned long long resultFactorial;
void Resume();
void Pause();
bool pause;
private:
QMutex sync;
QWaitCondition pauseCond;
// bool pause;
signals:
void NumberChanged(unsigned long long);
public slots:
};
MyThread.cpp
#include "mythread.h"
#include <QDebug>
#include <QMutex>
#include <QWaitCondition>
MyThread::MyThread(QObject *parent):QThread(parent)
{
pause = false;
}
void MyThread::run()
{
QMutex mutex;
int n = inputNumber;
unsigned long long factorial = 1;
// qDebug() << "Enter a positive integer: ";
// cin >> n;
mutex.lock();
if (n < 0)
qDebug() << "Error! Factorial of a negative number doesn't exist.";
else {
for(int i = 1; i <=n; ++i) {
sync.lock();
if(pause)
pauseCond.wait(&sync); // in this place, your thread will stop to execute until someone calls resume
qDebug() << "Paused for now" << pause;
sync.unlock();
factorial *= i;
MyThread().msleep(1000);
emit NumberChanged(factorial);
}
qDebug() << "Factorial of " << n << " = " << factorial;
}
resultFactorial = factorial;
mutex.unlock();
// return factorial;
}
void MyThread::Resume()
{
sync.lock();
pause = false;
sync.unlock();
pauseCond.wakeAll();
}
void MyThread::Pause()
{
sync.lock();
pause = true;
sync.unlock();
}
Dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include "mythread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = nullptr);
~Dialog();
MyThread *mThread;
private:
Ui::Dialog *ui;
public slots:
void onNumberChanged(unsigned long long);
private slots:
void on_startPrime_clicked();
void on_suspendPrime_clicked();
void on_resumePrime_clicked();
void on_stopPrime_clicked();
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include "mythread.h"
#include <QDebug>
//bool pauseCondition = false;
int statusOfPrimeThread = 0;
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
, ui(new Ui::Dialog)
{
ui->setupUi(this);
mThread = new MyThread(this);
connect(mThread, SIGNAL(NumberChanged(long)), this, SLOT(onNumberChanged(long)));
ui->activeStatePrime->setText(QString("Not Started"));
// connect(this, SIGNAL(on_resumePrime_clicked), mThread, SLOT(Resume()));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::onNumberChanged(unsigned long long Number)
{
qDebug() << QString::number(17196083355034583040ull);
ui->resultPrime->setText(QString::number(Number));
}
void Dialog::on_startPrime_clicked()
{
// Started
mThread->inputNumber = ui->lineEditPrime->text().toInt();
mThread->start();
if(mThread->isRunning()){
ui->activeStatePrime->setText(QString("Started"));
}
qDebug() << QString::number(17196083355034583040ull);
}
void Dialog::on_suspendPrime_clicked()
{
//Stopped
// mThread->terminate();
// pauseCondition = true;
// mThread->pause = pauseCondition;
mThread->Pause();
ui->activeStatePrime->setText(QString("Paused"));
}
void Dialog::on_resumePrime_clicked()
{
mThread->Resume();
ui->activeStatePrime->setText(QString("Resumed"));
}
void Dialog::on_stopPrime_clicked()
{
mThread->terminate();
ui->activeStatePrime->setText(QString("Terminated"));
}
But the label is not changed. How can I set such a large value, and I am correctly using unsigned long long datatype or is there any other datatype that can be used.

Related

Color channels are changing using Qt QImage with data and I don't know why

I have written a function in Qt to extract the data out of an image for the purpose of manipulating it.
I then have another function to reinsert the data back to an image and display it. The problem I am having is that even if I do no manipulation on the pixel data other than extract and reinsert, it is still changing the data. On a yellow image it changes it to turquoise blue when it should remain yellow.
I am including the function code to extract and reinsert as specimen code. I can include more if it is needed such as the display function etc...Does anyone know if I am doing something wrong?
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
filter = "All Picture Files (*.png *.jpg *.jpeg *.bmp *.tif *.tiff)"
";; Bitmap Files (*.bmp) ;; JPEG (*.jpg *.jpeg) ;; PNG (*.png) ;; TIFF (*.tif *.tiff)";
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::importImage()
{
importCancelled = false;
QString filename = QFileDialog::getOpenFileName(nullptr, QObject::tr("Import Image"), "", filter);
if(!filename.isEmpty()){
image.load(filename);
image = image.convertToFormat(QImage::Format_RGBA8888);
}
else {
importCancelled = true;
if(importCancelled){
QString cleanPlateCancelled = "Operation Cancelled";
ui->statusBar->showMessage(cleanPlateCancelled,5000);
return;
}
}
}
void MainWindow::scaleImage()
{
if (image.isNull()){
return;
}
else {
image = image.scaledToHeight(ui->view->height(), Qt::TransformationMode::SmoothTransformation);
}
}
void MainWindow::displayImage()
{
if (image.isNull()){
return;
}
else {
scene = new QGraphicsScene;
showImage = new QGraphicsPixmapItem(QPixmap::fromImage(image));
scene->addItem(showImage);
ui->view->setScene(scene);
}
}
void MainWindow::rgbaExtraction()
{
numberOfBytes = static_cast<uint>(image.sizeInBytes());
auto const imageData = image.bits();
rgba = std::vector<uchar>(numberOfBytes,0);
rgbaReset = std::vector<uchar>(numberOfBytes,0);
for (uint i{0}; i < numberOfBytes; ++i) {
rgbaReset[i] = rgba[i] = imageData[i];
}
}
void MainWindow::rgbaInsertion()
{
auto *imageData = new uchar[numberOfBytes];
for (uint i{0};i < numberOfBytes;++i) {
imageData[i] = rgba[i];
}
image = QImage(imageData, image.width(), image.height(), QImage::Format_RGBA8888);
}
void MainWindow::on_importButton_clicked()
{
importImage();
scaleImage();
displayImage();
rgbaExtraction();
}
void MainWindow::on_quitButton_clicked()
{
QApplication::quit();
}
void MainWindow::sceneUpdater()
{
showImage->setPixmap(QPixmap::fromImage(image));
scene->update();
ui->view->update();
}
void MainWindow::on_redSlider_valueChanged(int value)
{
QString redString = QString::number(value);
ui->redLabel->setText(redString);
redDelta = value;
colorRed();
rgbaInsertion();
sceneUpdater();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QImage>
#include <QFileDialog>
#include <string>
#include <QGraphicsScene>
#include <QGraphicsPixmapItem>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_importButton_clicked();
void on_quitButton_clicked();
void on_redSlider_valueChanged(int value);
private:
QGraphicsPixmapItem *showImage;
QGraphicsScene *scene;
QString filter;
QImage image;
bool importCancelled;
QStatusBar *statusBar;
uint numberOfBytes;
std::vector<uchar> rgba;
std::vector<uchar> rgbaReset;
int redDelta{0};
int greenDelta{0};
int blueDelta{0};
int opacityDelta{0};
void importImage();
void scaleImage();
void displayImage();
void rgbaExtraction();
void rgbaInsertion();
void sceneUpdater();
void colorRed(); // Implemented in color.cpp
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
color.cpp
#include <mainwindow.h>
void MainWindow::colorRed()
{
for (uint i{0}; i < rgba.size()*sizeof (rgba[i]);i+=4) {
if(rgbaReset[i] + static_cast<uchar>(redDelta)>=255){
rgba[i] = 255;
}
else {
rgba[i] = rgbaReset[i];// + static_cast<uchar>(redDelta);
}
}
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
The problem is in scaleImage(), because scaledToHeight() returns another image format. You may omit the scale operation, or convert the returned image to Format_RGBA8888:
void MainWindow::scaleImage()
{
if (image.isNull()){
return;
}
else {
image = image.scaledToHeight(ui->view->height(), Qt::TransformationMode::SmoothTransformation)
.convertToFormat(QImage::Format_RGBA8888);
}
}
My recomendation is to add some instrumentation after each image manipulation to check that it has the expected format:
qDebug() << Q_FUNC_INFO << "image format:" << image.format();

How to save recordings to *.wav?

I trying to change my code to save recordings to wav-files. Later i have to import this to MATLAB.
Its works to save like .*pcm or.*wav. But I want play it with (example VLC Player) external player.
QAudioFormat format;
Conf values;
format.setSampleRate(values.getSampRate());
format.setChannelCount(values.getChannel());
format.setSampleSize(values.getSampSize());
format.setCodec(values.getCodec());
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);
in config-file i have configuration:
samp_rate=88200
channel=1
samp_size=24
codec=Audio/PCM
byte_order=QAudioFormat::LittleEndian
sample_type=QAudioFormat::SignedInt
Saving file looks:
m_audio->startrecording(fn+".pcm");
I changed pcm to wav - file will be recorded, but I cant open it with VLC (just import to Audacity with manual input of sample Rate, ByteOrder). Its because of RAW-data? how can able to save my recording like wav-file included sample-size, sampl-rate ...?
Audio.cpp
// ************************************************************************************************
// Audio-Class
// ************************************************************************************************
#include "Audio.h"
#include "Conf.h"
#include "Measure.h"
// ************************************************************************************************
Audio::Audio(Conf *conf)
{
m_conf = conf;
AudioRecord();
}
// ************************************************************************************************
//Initialization and signal-slot connection
void Audio::AudioRecord()
{
QAudioFormat format;
Conf values;
format.setSampleRate(values.getSampRate());
format.setChannelCount(values.getChannel());
format.setSampleSize(values.getSampSize());
format.setCodec(values.getCodec());
format.setByteOrder(QAudioFormat::LittleEndian);
format.setSampleType(QAudioFormat::SignedInt);
QAudioDeviceInfo info = QAudioDeviceInfo::defaultInputDevice();
if (!info.isFormatSupported(format))
{
qWarning() << "Default format not supported";
format = info.nearestFormat(format);
}
m_audio = new QAudioInput(format, this);
connect(m_audio, SIGNAL(stateChanged(QAudio::State)), this, SLOT(handleStateChanged(QAudio::State)));
}
// ************************************************************************************************
//Start recording method
void Audio::startrecording(QString rec_file_path)
{
m_file.setFileName(rec_file_path);
m_file.open(QIODevice::WriteOnly);
m_audio->start(&m_file);
}
// ************************************************************************************************
//Stop recording
void Audio::stoprecording()
{
m_audio->stop();
m_file.close();
}
// ************************************************************************************************
//Recording DEBUG output
void Audio::handleStateChanged(QAudio::State newState)
{
switch (newState)
{
case QAudio::StoppedState:
if (m_audio->error() != QAudio::NoError)
{
qDebug() << "Error!!";
} else
{
qDebug() << "Finished recording";
}
break;
case QAudio::ActiveState:
qDebug() << "Started recording";
break;
default:
break;
}
}
// ************************************************************************************************
Audio.h
// ************************************************************************************************
// Audio-HEADER-file
// ************************************************************************************************
#ifndef AUDIO_H
#define AUDIO_H
// ************************************************************************************************
// Includes
#include <QDebug>
#include <QObject>
#include "Conf.h"
#include <QAudioInput>
#include <QDateTime>
#include <QTimer>
// ************************************************************************************************
// Define
#define SAVE_AUDIO_PATH "/home/nikitajarocky/workspace/QT/UART_PC/IO/"
// ************************************************************************************************
// Class variables and methods
class Audio : public QObject
{
Q_OBJECT
public:
explicit Audio(Conf *conf);
void start(QString file_name);
void stop();
void startrecording(QString);
void stoprecording();
signals:
public slots:
void handleStateChanged(QAudio::State);
void AudioRecord();
private:
Conf *m_conf;
Conf *m_samp_rate;
QAudioInput *m_audio;
QFile m_file;
};
// ************************************************************************************************
#endif // AUDIO_H
A much simpler approach is use QAudioRecorder, it handles the writing of the header and also handles the audio capture.
It saves you from big changes, if your goal is only recording.
See the example:
audio.h:
#ifndef AUDIO_H
#define AUDIO_H
#include <QtCore>
#include <QtMultimedia>
class Audio : public QObject
{
Q_OBJECT
public:
explicit Audio(QObject *parent = nullptr);
~Audio();
public slots:
QStringList audioInputs();
bool record(const QString &path, const QString &audio_input = QString());
void stop();
private:
QAudioRecorder *m_recorder;
};
#endif // AUDIO_H
audio.cpp:
#include "audio.h"
Audio::Audio(QObject *parent) : QObject(parent)
{
m_recorder = new QAudioRecorder(this);
}
Audio::~Audio()
{
stop();
}
QStringList Audio::audioInputs()
{
return m_recorder->audioInputs();
}
bool Audio::record(const QString &path, const QString &audio_input)
{
QAudioEncoderSettings audio_settings;
audio_settings.setCodec("audio/pcm");
audio_settings.setChannelCount(1);
audio_settings.setSampleRate(44100);
m_recorder->setEncodingSettings(audio_settings);
m_recorder->setOutputLocation(path);
m_recorder->setAudioInput(audio_input);
m_recorder->record();
if (m_recorder->state() == QAudioRecorder::RecordingState)
{
qDebug() << "Recording...";
return true;
}
else
{
qDebug() << qPrintable(m_recorder->errorString());
return false;
}
}
void Audio::stop()
{
if (m_recorder->state() == QAudioRecorder::RecordingState)
{
m_recorder->stop();
qDebug() << "Recording stopped";
}
else
{
qDebug() << "Nothing to stop";
}
}
Usage example (recording 5 seconds):
#include <QtCore>
#include "audio.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Audio audio;
audio.record("file.wav");
QTimer::singleShot(5 * 1000, &audio, &Audio::stop);
return a.exec();
}

QWebEngine download restart after a reboot

I did an application to download softwares. It's works well with QWebengine.
For the second version, I need to implement the restart of the download after the application is turned off.
My goal is to get possible to restart the same download at the same status after a reboot.
Is it possible?
How to save the status of the current download in a file with WebEngineDownloadItem ?
Thank you for your help
This is how I did :
DownloaderWidget.hpp
#ifndef DOWNLOADERWIDGET_HPP
#define DOWNLOADERWIDGET_HPP
# include <QUrl>
# include <QApplication>
# include <QPushButton>
# include <QString>
# include <QWidget>
# include <QLabel>
# include <QVBoxLayout>
# include <QProgressBar>
# include "downloadermanager.hpp"
class DownloaderWidget : public QWidget
{
Q_OBJECT
public:
explicit DownloaderWidget(QWidget *parent = nullptr);
signals:
public slots:
void download(void);
void pause(void);
void resume(void);
private slots:
void progress(int percent);
private:
static QString const
URL;
QLabel *m_url;
QPushButton *m_start;
QPushButton *m_resume;
QPushButton *m_pause;
QProgressBar *m_status;
DownloaderManager *m_download_manager;
};
#endif // DOWNLOADERWIDGET_HPP
DownloaderManager.hpp
#ifndef DOWNLOADERMANAGER_HPP
#define DOWNLOADERMANAGER_HPP
# include <QUrl>
# include <QObject>
# include <QDebug>
# include <QNetworkAccessManager>
# include <QNetworkRequest>
# include <QNetworkReply>
# include <QFile>
# include <QByteArray>
# include <QStandardPaths>
class DownloaderManager : public QObject
{
Q_OBJECT
public:
explicit DownloaderManager(QObject *parent = nullptr);
signals:
void downloadComplete(void);
void progress(int const percentage);
public slots:
void download(QUrl const &url);
void pause();
void resume();
private slots:
void download(QNetworkRequest &request);
void finished();
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
void error(QNetworkReply::NetworkError code);
private:
QNetworkAccessManager
*m_manager;
QNetworkRequest m_request;
QNetworkReply *m_reply;
QFile *m_file;
qint64 m_downloadSizeAtPause;
QString m_name;
QString get_file_name(QUrl const &url);
};
#endif // DOWNLOADERMANAGER_HPP
DownloaderWidget.cpp
#include "downloaderwidget.hpp"
QString const DownloaderWidget::URL = "My great URL";
DownloaderWidget::DownloaderWidget(QWidget *parent)
: QWidget(parent),
m_url(new QLabel(URL, this)),
m_start(new QPushButton("Start", this)),
m_resume(new QPushButton("Resume", this)),
m_pause(new QPushButton("Pause", this)),
m_status(new QProgressBar(this)),
m_download_manager(new DownloaderManager(this))
{
QVBoxLayout *main_layout = new QVBoxLayout(this);
m_status->setOrientation(Qt::Horizontal);
main_layout->addWidget(m_url);
main_layout->addWidget(m_status);
main_layout->addWidget(m_start);
main_layout->addWidget(m_pause);
main_layout->addWidget(m_resume);
QObject::connect(m_start, SIGNAL(clicked()), this, SLOT(download()));
QObject::connect(m_pause, SIGNAL(clicked()), this, SLOT(pause()));
QObject::connect(m_resume, SIGNAL(clicked()), this, SLOT(resume()));
QObject::connect(m_download_manager, SIGNAL(downloadComplete()), qApp, SLOT(quit()));
QObject::connect(m_download_manager, SIGNAL(progress(int)), this, SLOT(progress(int)));
this->m_pause->setEnabled(false);
this->m_resume->setEnabled(false);
}
void DownloaderWidget::download(void)
{
this->m_download_manager->download(QUrl(URL));
this->m_start->setEnabled(false);
this->m_pause->setEnabled(true);
}
void DownloaderWidget::pause()
{
this->m_download_manager->pause();
this->m_pause->setEnabled(false);
this->m_resume->setEnabled(true);
}
void DownloaderWidget::resume(void)
{
this->m_download_manager->resume();
this->m_pause->setEnabled(true);
this->m_resume->setEnabled(false);
}
void DownloaderWidget::progress(int percent)
{
this->m_status->setValue(percent);
}
DownloaderManager.cpp
#include "downloadermanager.hpp"
DownloaderManager::DownloaderManager(QObject *parent) :
QObject(parent),
m_manager(new QNetworkAccessManager(this)),
m_request(),
m_reply(nullptr),
m_file(nullptr),
m_downloadSizeAtPause(0),
m_name("")
{
}
QString DownloaderManager::get_file_name(QUrl const &url)
{
QStringList list = url.toString().split("/");
this->m_name = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + "/" + list[list.length() - 1];
return (this->m_name + ".download");
}
void DownloaderManager::download(QUrl const &url)
{
this->m_name = this->get_file_name(url);
qDebug() << "Download : file = " << this->m_name;
this->m_downloadSizeAtPause = 0;
this->m_request = QNetworkRequest(url);
this->m_file = new QFile(this->m_name);
this->m_file->open(QIODevice::ReadWrite | QIODevice::Append);
if (this->m_file->size() != 0)
this->resume();
else
this->download(this->m_request);
}
void DownloaderManager::pause(void)
{
qDebug() << "pause()";
if(this->m_reply == nullptr)
return;
QObject::disconnect(this->m_reply, SIGNAL(finished()), this, SLOT(finished()));
QObject::disconnect(this->m_reply, SIGNAL(downloadProgress(qint64, qint64)),
this, SLOT(downloadProgress(qint64, qint64)));
QObject::disconnect(this->m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(error(QNetworkReply::NetworkError)));
this->m_reply->abort();
this->m_file->write(this->m_reply->readAll());
this->m_reply = nullptr;
}
void DownloaderManager::resume(void)
{
qDebug() << "resume()";
this->m_file->flush();
this->m_downloadSizeAtPause = this->m_file->size();
QByteArray rangeHeaderValue = "bytes=" + QByteArray::number(this->m_downloadSizeAtPause) + "-";
this->m_request.setRawHeader("Range",rangeHeaderValue);
this->download(this->m_request);
}
void DownloaderManager::download(QNetworkRequest &request)
{
qDebug() << "download( QNetworkRequest& request )";
this->m_reply = this->m_manager->get(request);
QObject::connect(this->m_reply, SIGNAL(finished()), this, SLOT(finished()));
QObject::connect(this->m_reply, SIGNAL(downloadProgress(qint64, qint64)),
this, SLOT(downloadProgress(qint64, qint64)));
QObject::connect(this->m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(error(QNetworkReply::NetworkError)));
}
void DownloaderManager::finished(void)
{
qDebug() << "finihsed";
this->m_file->rename(this->m_name + ".download", this->m_name);
this->m_file->close();
this->m_file = nullptr;
this->m_reply = nullptr;
emit downloadComplete();
}
void DownloaderManager::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
{
qDebug() << "Download Progress: Received=" << this->m_downloadSizeAtPause + bytesReceived <<": Total=" << this->m_downloadSizeAtPause + bytesTotal;
this->m_file->write(this->m_reply->readAll());
int percentage =
static_cast<int>((this->m_downloadSizeAtPause + bytesReceived) * 100 ) / (this->m_downloadSizeAtPause + bytesTotal);
qDebug() << percentage;
emit progress(percentage);
}
void DownloaderManager::error(QNetworkReply::NetworkError code)
{
qDebug() << "Error:" <<code;
}
main.cpp
#include <QApplication>
#include "downloaderwidget.hpp"
int main(int argc, char **argv)
{
QApplication app(argc, argv);
DownloaderWidget downloader;
downloader.show();
return (app.exec());
}
I hope this piece of code will help some one in the same case than me Thank you

Transfer serially into Arduino Uno, the text file read by Qt Creator

This is from my previous question of read the text line by line.
Based from #KubaOber answer, I can successfully read and display the content line by line in a certain time interval.
Then, I was trying to transmit the content of the text file serially into Arduino Uno using the source code available on the internet.
Here's the header code:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtSerialPort/QSerialPort>
#include <QSerialPortInfo>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
QSerialPort *arduino;
static const quint16 arduino_uno_vendor_id = 10755;
static const quint16 arduino_uno_product_id = 67;
QString arduino_port_name;
bool arduino_is_available;
QByteArray serialData;
QString serialBuffer;
void updateSpeedometer(QString);
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
Ui::Widget *ui;
private slots:
private:
};
#endif // WIDGET_H
and here's the main.cpp :
#include <QtWidgets>
#include <QSerialPortInfo>
#include <QtSerialPort/QSerialPort>
#include "widget.h"
#include <QDebug>
bool arduino_is_available = false;
QString arduino_port_name = "";
QSerialPort *arduino = new QSerialPort;
QString serialBuffer = "";
static const quint16 arduino_uno_vendor_id = 10755;
static const quint16 arduino_uno_product_id = 67;
class PeriodicReader : public QObject {
Q_OBJECT
QTimer m_timer{this};
QFile m_file{this};
void readLine() {
if (m_file.atEnd()) {
m_timer.stop();
return;
}
QByteArray lineBaru(m_file.readLine());
emit newLine(lineBaru);
qDebug()<<lineBaru;
QString lineString(lineBaru);
qDebug()<<lineString << " converted to QString";
lineString.remove("\n");
qDebug()<<lineString;
lineString.remove(" ");
qDebug()<<lineString;
QRegExp rx("d(\\d+)");
QList<int> list;
int pos = 0;
while ((pos = rx.indexIn(lineString, pos)) != -1) {
list << rx.cap(1).toInt();
pos += rx.matchedLength();
}
qDebug()<<list;
int listi = list.at(0);
qDebug()<<"list[0] :"<<listi;// <<---THIS IS WHERE I CAN GET THE VALUE AFTER THE "d"
updateSpeedometer(lineString);
}
void updateSpeedometer(QString command)
{
if(arduino->isWritable())
{
command.remove(" ");
arduino->write(command.toStdString().c_str());
qDebug() << command.toStdString().c_str() << " is uploaded to Arduino";
}else{
qDebug()<<"Couldn't write to Serial !" ;
}
}
public:
explicit PeriodicReader(QObject * parent = {}) : QObject(parent) {
connect(&m_timer, &QTimer::timeout, this, &PeriodicReader::readLine);
}
void load(const QString & fileName) {
m_file.close(); // allow re-opening of the file
m_file.setFileName(fileName);
if (m_file.open(QFile::ReadOnly | QFile::Text)) {
readLine();
m_timer.start(1000); // <<<---------------HERE IS WHERE I WANT THE DELAY TO BE
}
}
Q_SIGNAL void newLine(const QByteArray &);
};
QString lineToString(QByteArray line)
{
while (line.endsWith('\n') || line.endsWith('\r'))
line.chop(1);
return QString::fromUtf8(line);
}
int main(int argc, char ** argv) {
qDebug()<<"Number of available ports :" <<QSerialPortInfo::availablePorts().length();
foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()){
qDebug()<<"Has Vendor ID:" << serialPortInfo.hasVendorIdentifier();
if(serialPortInfo.hasVendorIdentifier()){
qDebug()<<"Vendor ID:"<< serialPortInfo.vendorIdentifier();
}
qDebug()<<"Has Product ID:" << serialPortInfo.hasProductIdentifier();
if(serialPortInfo.hasProductIdentifier()){
qDebug()<<"Product ID:"<< serialPortInfo.productIdentifier();
}
}
foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts()){
if(serialPortInfo.hasVendorIdentifier() && serialPortInfo.hasProductIdentifier()){
if(serialPortInfo.vendorIdentifier() == arduino_uno_vendor_id){
if(serialPortInfo.productIdentifier() == arduino_uno_product_id){
arduino_port_name = serialPortInfo.portName();
arduino_is_available = true;
}
}
}
}
if(arduino_is_available){
//open and configure the serialport
arduino->setPortName(arduino_port_name);
arduino->open(QSerialPort::ReadWrite);
arduino->setBaudRate(QSerialPort::Baud9600);
arduino->setDataBits(QSerialPort::Data8);
arduino->setParity(QSerialPort::NoParity);
arduino->setStopBits(QSerialPort::OneStop);
arduino->setFlowControl(QSerialPort::NoFlowControl);
//QObject::connect(arduino,SIGNAL(readyRead()),this,SLOT(readSerial()));
}else{
//show error message
qDebug()<<" Port Error, Couldn't find the Arduino' !";
// QMessageBox::warning(this, "Port Error, Couldn't find the Arduino !");
}
QApplication app{argc, argv};
QWidget window;
QVBoxLayout layout{&window};
QPushButton load{"Load"};
QPlainTextEdit edit;
layout.addWidget(&load);
layout.addWidget(&edit);
window.show();
PeriodicReader reader;
QObject::connect(&load, &QPushButton::clicked, [&]{
auto name = QFileDialog::getOpenFileName(&window);
if (!name.isEmpty()) {
edit.clear(); // allow re-opening of the file
reader.load(name);
}
});
QObject::connect(&reader, &PeriodicReader::newLine, &edit,
[&](const QByteArray & line){ edit.appendPlainText(lineToString(line)); });
return app.exec();
}
#include "main.moc"
It is from the coding of "reading text line by line" I've asked months a go which I include the arduino serial connection coding as well and hey, it worked!
It reads the text line by line and when each line is displayed in textEdit, it also transmitted to Arduino Uno.
So my request is, instead of the delay between line by line is preset at 2 seconds, can the delay duration be controlled by the content of the text file?
Let say.. the first line content inside the text file is 's200 d300' , and the 's200' is processed by arduino to generate a frequency, meanwhile 'd300' is the delay interval in milliseconds before it reads the next line and generate another frequency signal.
So,how to make Qt recognise the 'd300' and use it as the delay value?
QString str = "asa24fsesfd300kslfv0";
QTextDocument document(str);
QTextCursor d = document.find("d");
qDebug()<<d.position();
QString s = str.mid(d.position()-1,6); // How many digits can be after << d >>
int count = 0;
for (int i = 1; i < s.size(); ++i) {
QString d = s.at(i);
if(d.isEmpty()){
break;
}else{
bool ok;
int k = d.toInt(&ok);
if(ok){
count++;
}else{
break;
}
}
}
QString result = str.mid(d.position(),count);
bool ok;
int result_int = result.toInt(&ok);
if(ok){
qDebug()<< result_int;
}
result 300

QTcpSocket communication in a thread

I'm making two application : one is the server and one is the client. The server use QTcpServer and QThread to listen to client. The client use QThread to make a connection to server.
The server and the client successfully connected, but the problem is how to communicate data between them. On server side, I put a line to send a data to client using socket->write("hello") when a new client is connected, but the client didn't receive it. The "didn't receive" conjecture based on nothing written on calling QDebug on client side.
Also, I want to ask about how to make the client thread always ready to receive data from server but sometimes can be used to send data to server when a PushButton is used.
Any help will be appreciated.
client side main.cpp (using a widget)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "tcpthread.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
TcpThread *tcpThread = new TcpThread(this);
connect(tcpThread, SIGNAL(finished()), tcpThread, SLOT(deleteLater()));
tcpThread->start();
}
client side tcpthread.h
#ifndef TCPTHREAD_H
#define TCPTHREAD_H
#include <QThread>
#include <QTcpSocket>
class TcpThread : public QThread
{
Q_OBJECT
public:
explicit TcpThread(QObject *parent = 0);
void run();
signals:
void error(QTcpSocket::SocketError socketError);
public slots:
void readyRead();
void disconnected();
private:
void processMessage(QByteArray message);
QTcpSocket *socket;
qintptr socketDescriptor;
QByteArray data;
};
#endif // TCPTHREAD_H
client side tcpthread.cpp
#include "tcpthread.h"
TcpThread::TcpThread(QObject *parent) :
QThread(parent)
{
}
void TcpThread::run()
{
qDebug() << "Thread started";
socket = new QTcpSocket();
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
socket->connectToHost("127.0.0.1",1234);
exec();
}
void TcpThread::readyRead()
{
data = socket->readAll();
while(!data.contains('\n'))
{
socket->waitForReadyRead();
data += socket->readAll();
}
int bytes = data.indexOf('\n')+1;
QByteArray message = data.left(bytes);
data = data.mid(bytes);
qDebug() << socketDescriptor << " : " << message;
processMessage(message);
}
void TcpThread::disconnected()
{
qDebug() << socketDescriptor << " disconnected";
socket->deleteLater();
exit(0);
}
void TcpThread::processMessage(QByteArray message)
{
qDebug() << message << " processed";
}
server side main.cpp
#include "tcpserver.h"
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
TcpServer tcpServer;
tcpServer.startServer();
return a.exec();
}
server side tcpthread.h
#ifndef TCPTHREAD_H
#define TCPTHREAD_H
#include <QThread>
#include <QTcpSocket>
#include <QDebug>
class TcpThread : public QThread
{
Q_OBJECT
public:
explicit TcpThread(qintptr ID, QObject *parent = 0);
void run();
signals:
void error(QTcpSocket::SocketError socketError);
public slots:
void readyRead();
void disconnected();
private:
void processMessage(QByteArray message);
QTcpSocket *socket;
qintptr socketDescriptor;
QByteArray data;
};
#endif // TCPTHREAD_H
server side tcpthread.cpp
#include "tcpthread.h"
TcpThread::TcpThread(qintptr ID, QObject *parent) :
QThread(parent)
{
this->socketDescriptor = ID;
}
void TcpThread::run()
{
qDebug() << "Thread started";
socket = new QTcpSocket();
if(!socket->setSocketDescriptor(this->socketDescriptor))
{
emit error(socket->error());
return;
}
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
qDebug() << socketDescriptor << " connected";
socket->write("hello");
exec();
}
void TcpThread::readyRead()
{
data = socket->readAll();
while(!data.contains('\n'))
{
socket->waitForReadyRead();
data += socket->readAll();
}
int bytes = data.indexOf('\n')+1;
QByteArray message = data.left(bytes);
data = data.mid(bytes);
qDebug() << socketDescriptor << " : " << message;
processMessage(message);
//socket->write(data);
}
void TcpThread::disconnected()
{
qDebug() << socketDescriptor << " disconnected";
socket->deleteLater();
exit(0);
}
void TcpThread::processMessage(QByteArray message)
{
qDebug() << message << " processed";
}

Resources