qextserialport write and progress bar
-
Hi,
Did you take into account the remarks of @JonB ? If not, then there lies your issue. If you send a big file in one big chunk, the event loop will be blocked until all data was sent and thus cannot refresh the UI.
Thank you for your replay!
Now I see that
But I still do not undrestand how to do right portion of data.. -
Thank you for your replay!
Now I see that
But I still do not undrestand how to do right portion of data..It's up to you split the file size into some reasonable size. You could use 4k blocks for example.
-
It's up to you split the file size into some reasonable size. You could use 4k blocks for example.
@SGaist
Thanks, I did that but still in CentOS instead of progress bar in window I see black screenQByteArray y; QByteArray arr; if (!file.open(QIODevice::ReadOnly)) { QMessageBox::information(this, tr("can't open"), file.errorString()); return; } else { arr.resize(fls); for(unsigned long i; i<fls;i++) {arr = 0;} arr = file.readAll(); while (!file.atEnd()); file.close(); } bar->setRange(1, fls); unsigned long i; for(i=0;i<fls;i++) { bar->setValue(i); y = arr.mid(i, 1 ); port->write(y); } bar->setValue(fls);
-
@SGaist
Thanks, I did that but still in CentOS instead of progress bar in window I see black screenQByteArray y; QByteArray arr; if (!file.open(QIODevice::ReadOnly)) { QMessageBox::information(this, tr("can't open"), file.errorString()); return; } else { arr.resize(fls); for(unsigned long i; i<fls;i++) {arr = 0;} arr = file.readAll(); while (!file.atEnd()); file.close(); } bar->setRange(1, fls); unsigned long i; for(i=0;i<fls;i++) { bar->setValue(i); y = arr.mid(i, 1 ); port->write(y); } bar->setValue(fls);
@another_one
I have no idea whether you have a CentOS issue with physically showing the progress bar. But you do realise that with your code you likely won't see any progress at all, you will simply see the bar at 100% complete at the end? The UI will not be updated during yourfor
loop callingbar->setValue(i)
because (so far as I know)port->write()
doesn't yield for that, it won't be refreshed till after thebar->setValue(fls)
.You can test the progress bar drawing with a simple
QTimer()
timing out, say, once per second and causing in increment; not your code with afor
loop orport->write()
. that would tell you whether the CentOS progress bar drawing is working. -
@another_one
I have no idea whether you have a CentOS issue with physically showing the progress bar. But you do realise that with your code you likely won't see any progress at all, you will simply see the bar at 100% complete at the end? The UI will not be updated during yourfor
loop callingbar->setValue(i)
because (so far as I know)port->write()
doesn't yield for that, it won't be refreshed till after thebar->setValue(fls)
.You can test the progress bar drawing with a simple
QTimer()
timing out, say, once per second and causing in increment; not your code with afor
loop orport->write()
. that would tell you whether the CentOS progress bar drawing is working.@JonB
sorry, i forgot to say what this code on Ws works well
I just compile it in cent os and all is work except progress bar bag with black screen instead -
@JonB
sorry, i forgot to say what this code on Ws works well
I just compile it in cent os and all is work except progress bar bag with black screen instead@another_one Your current code can't work. As long as the for loop calling bar->setValue(i) is running Qt event loop is blocked and the progress bar will not update or even be black or whatever.
You could call https://doc.qt.io/qt-6/qcoreapplication.html#processEvents inside same loop, but that is a ugly work around. Proper solution in this case would be to move the serial port handling into another thread and emit a signal from that thread every time you want to update the progress bar. -
@another_one Your current code can't work. As long as the for loop calling bar->setValue(i) is running Qt event loop is blocked and the progress bar will not update or even be black or whatever.
You could call https://doc.qt.io/qt-6/qcoreapplication.html#processEvents inside same loop, but that is a ugly work around. Proper solution in this case would be to move the serial port handling into another thread and emit a signal from that thread every time you want to update the progress bar.@jsulm
Thank you for your advice!
I already use serial port handling but only when I read:connect(port, SIGNAL(readyRead()), this, SLOT(readData()));
And here I use readyRead() emiting
In my byte by byte writing case, can I use bytesWritten(one byte) to increment, in thread, the progress bar ? -
@jsulm
Thank you for your advice!
I already use serial port handling but only when I read:connect(port, SIGNAL(readyRead()), this, SLOT(readData()));
And here I use readyRead() emiting
In my byte by byte writing case, can I use bytesWritten(one byte) to increment, in thread, the progress bar ? -
to increment, in thread, the progress bar ?
If you use another thread to do the serial port stuff you must not directly update the progress bar, you must send a signal from the serial thread to the main UI thread, like @jsulm wrote.
@JonB
Thank you, now I undestand for what I should do it
But can't imagine the construction itself
Can anybody give me an example?, please -
@JonB
Thank you, now I undestand for what I should do it
But can't imagine the construction itself
Can anybody give me an example?, please@another_one
What is there to say? Above you have code toconnect()
signal and slot, you need to do a connect here too. The https://doc.qt.io/qt-6/signalsandslots.html#a-small-example is enough to follow for your case. -
@another_one
What is there to say? Above you have code toconnect()
signal and slot, you need to do a connect here too. The https://doc.qt.io/qt-6/signalsandslots.html#a-small-example is enough to follow for your case.Thanks!
Ive done another thread but it got worse
First I set global variable of progress bar/ data iterationunsigned long ii = 0;
After Ive done the link:
connect(port, SIGNAL(bytesWritten(qint64)), this, SLOT(writeData(qint64))); void monMK::writeData(qint64) { bar->setValue(ii); qDebug() << "ii progress bar value" << ii; } void mM::on_open_folder_clicked() {// from button clicked .... .... .... bar = new QProgressDialog(this); port->write(dataArr4); bar->setLabelText(tr("loading...")); bar->setCancelButtonText(tr("&Cancel")); bar->setMinimumDuration(0); bar->setWindowTitle(tr("Loading")); bar->setVisible(1); qApp->processEvents(); bar->setValue(1); bar->setRange(1, fls-1); // where fls size of File stored for(ii=0;ii<fls;ii++) { y = arr.mid(ii, 1 ); / port->write(y,1); //port->waitForBytesWritten(1); } .... }
As result I see progress bar appering and stopping on 0 %
While in debug i see:
"
ii progress bar value 0
// several time waiting
ii progress bar value 77457
"
So please help! -
Thanks!
Ive done another thread but it got worse
First I set global variable of progress bar/ data iterationunsigned long ii = 0;
After Ive done the link:
connect(port, SIGNAL(bytesWritten(qint64)), this, SLOT(writeData(qint64))); void monMK::writeData(qint64) { bar->setValue(ii); qDebug() << "ii progress bar value" << ii; } void mM::on_open_folder_clicked() {// from button clicked .... .... .... bar = new QProgressDialog(this); port->write(dataArr4); bar->setLabelText(tr("loading...")); bar->setCancelButtonText(tr("&Cancel")); bar->setMinimumDuration(0); bar->setWindowTitle(tr("Loading")); bar->setVisible(1); qApp->processEvents(); bar->setValue(1); bar->setRange(1, fls-1); // where fls size of File stored for(ii=0;ii<fls;ii++) { y = arr.mid(ii, 1 ); / port->write(y,1); //port->waitForBytesWritten(1); } .... }
As result I see progress bar appering and stopping on 0 %
While in debug i see:
"
ii progress bar value 0
// several time waiting
ii progress bar value 77457
"
So please help!@another_one What is the size of the file?
There is no need for any global variables, simply use the parameter of your slot:void monMK::writeData(qint64 ii) { bar->setValue(ii); qDebug() << "ii progress bar value" << ii; }
You should stop using old connect syntax.
The actual issue is that you write the data in one blocking loop inside on_open_folder_clicked() - this blocks the Qt event loop. -
@another_one What is the size of the file?
There is no need for any global variables, simply use the parameter of your slot:void monMK::writeData(qint64 ii) { bar->setValue(ii); qDebug() << "ii progress bar value" << ii; }
You should stop using old connect syntax.
The actual issue is that you write the data in one blocking loop inside on_open_folder_clicked() - this blocks the Qt event loop.@jsulm said in qextserialport write and progress bar:
What is the size of the file?*
Thank you for your replay!
The size of File is 77457 Bytes
How can I transfer ii value from "button clicked" to slot writeData?, via port->waitForBytesWritten(ii);?
You should stop using old connect syntax.
The actual issue is that you write the data in one blocking loop inside on_open_folder_clicked() - this blocks the Qt event loop.*
Sorry, here, again, I didnt undestand
How can I fdo write data(write the File) in non-blocking state?, Can you give me an example how its possible to do unblocked file writing to qextserialport?, please
Cause I didnt undestand how "Code of Conduct" can help in this case
Thanks in advance! -
@jsulm said in qextserialport write and progress bar:
What is the size of the file?*
Thank you for your replay!
The size of File is 77457 Bytes
How can I transfer ii value from "button clicked" to slot writeData?, via port->waitForBytesWritten(ii);?
You should stop using old connect syntax.
The actual issue is that you write the data in one blocking loop inside on_open_folder_clicked() - this blocks the Qt event loop.*
Sorry, here, again, I didnt undestand
How can I fdo write data(write the File) in non-blocking state?, Can you give me an example how its possible to do unblocked file writing to qextserialport?, please
Cause I didnt undestand how "Code of Conduct" can help in this case
Thanks in advance!@another_one Please take a look at this example application: https://doc.qt.io/qt-5/qtserialport-cwriterasync-example.html
-
@another_one Please take a look at this example application: https://doc.qt.io/qt-5/qtserialport-cwriterasync-example.html
Thank you for this example!
It' seems to be what I need, but I wanted to clarify about progress bar using in SerialPortWriter class, - can I increment progress bar in :handleBytesWritten ??Thank you!
-
Thank you for this example!
It' seems to be what I need, but I wanted to clarify about progress bar using in SerialPortWriter class, - can I increment progress bar in :handleBytesWritten ??Thank you!
@another_one emit a signal from that class and connect that one to the progress bar. That way you avoid leaking GUI knowledge in your business logic class.
-
@another_one emit a signal from that class and connect that one to the progress bar. That way you avoid leaking GUI knowledge in your business logic class.
Thank you!
I'm trying doing in this way but when I connect my signal the program exit and closed automatically :My class:
class qextserpw : public QObject { Q_OBJECT public: // explicit qextserpw(QObject *parent = nullptr); explicit qextserpw(QextSerialPort *serialPort, QObject *parent = nullptr); void write(const QByteArray &writeData); //private slots: public slots: void handleBytesWritten(qint64 bytes); private: QextSerialPort *m_serialPort = nullptr; QByteArray m_writeData; qint64 m_bytesWritten = 0; signals: void inprogress(unsigned long progr); }; #endif // QEXTSERPW_H
#include <QtDebug> #include <QtGlobal> #include <QtCore> #include <QProgressDialog> //qextserpw::qextserpw(QObject *parent) : QObject(parent) qextserpw::qextserpw(QextSerialPort *serialPort, QObject *parent) { } void qextserpw::handleBytesWritten(qint64 bytes) { }
And these connection gots failed launch of program
:qextserpw *qextser; connect(qextser, SIGNAL(inprogress(int progr)), bar, SLOT(setValue(progr))); // or connect(qextser, SIGNAL( inprogress(int) ), bar, SLOT( setValue(int) ) );
-
Thank you!
I'm trying doing in this way but when I connect my signal the program exit and closed automatically :My class:
class qextserpw : public QObject { Q_OBJECT public: // explicit qextserpw(QObject *parent = nullptr); explicit qextserpw(QextSerialPort *serialPort, QObject *parent = nullptr); void write(const QByteArray &writeData); //private slots: public slots: void handleBytesWritten(qint64 bytes); private: QextSerialPort *m_serialPort = nullptr; QByteArray m_writeData; qint64 m_bytesWritten = 0; signals: void inprogress(unsigned long progr); }; #endif // QEXTSERPW_H
#include <QtDebug> #include <QtGlobal> #include <QtCore> #include <QProgressDialog> //qextserpw::qextserpw(QObject *parent) : QObject(parent) qextserpw::qextserpw(QextSerialPort *serialPort, QObject *parent) { } void qextserpw::handleBytesWritten(qint64 bytes) { }
And these connection gots failed launch of program
:qextserpw *qextser; connect(qextser, SIGNAL(inprogress(int progr)), bar, SLOT(setValue(progr))); // or connect(qextser, SIGNAL( inprogress(int) ), bar, SLOT( setValue(int) ) );
@another_one said in qextserialport write and progress bar:
qextserpw *qextser;
Don't you think this variable should contain a valid pointer before it's used?
-
@another_one said in qextserialport write and progress bar:
qextserpw *qextser;
Don't you think this variable should contain a valid pointer before it's used?
Unfortunally it doesn't help
qextserpw *qextser = new qextserpw(port); connect(port, SIGNAL(bytesWritten(qint64)), this, SLOT(writeData(qint64))); connect(qextser, SIGNAL( inprogress(int) ), bar, SLOT( setValue(int) ) );
-
Unfortunally it doesn't help
qextserpw *qextser = new qextserpw(port); connect(port, SIGNAL(bytesWritten(qint64)), this, SLOT(writeData(qint64))); connect(qextser, SIGNAL( inprogress(int) ), bar, SLOT( setValue(int) ) );
sorry, I forgot about bar initialization too
Now program can launch but I have got the same problem with progress bar...