[Solved] How to control QTimer and lineEdit
-
In my application I am reading the data from QProcess. And I am doing that splitting that data and displayed in line edit with some time delay using QTimer.
But I am unable to stop the timer when Qprocess stoped
Here is my code.
Here I am starting the QProcess
@
void Hmi1::on_start_AV_clicked()
{
QString program;
QStringList arguments;
program = "/home/IFSS/programs/VME/test";process =new QProcess(); process->setReadChannel(QProcess::StandardOutput); process->start(program,arguments); connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(read_AV()));
}
@
read_AV() slot and in this slot I am starting the timer
@
void Hmi1::read_AV()
{
QByteArray b1;
QStringList strLines;b1= process->readAllStandardOutput();
qDebug()<<QString::number(b1.length());
strLines = QString(b1).split("\n");
foreach (line_array1[a++], strLines) {; }timer = new QTimer(this);
timer->setSingleShot(false);
connect(timer, SIGNAL(timeout()), this, SLOT(updateText()));
timer->start(1000);
@timer slot is below
@
void Hmi1::updateText()
{
emit out(line_array1); //custom signal
connect(this,SIGNAL(out(QString *)),this,SLOT(disp(QString *)));
}
@displaying in QLine edit
@
void Hmi1::disp(QString *line_array1)
{
ui4->lineEdit_AIV1->setText(line_array1[k++]);
ui4->lineEdit_AIV11->setText(line_array1[k++]);ui4->lineEdit_AIV2->setText(line_array1[k++]); ui4->lineEdit_AIV22->setText(line_array1[k++]); ui4->lineEdit_AIV3->setText(line_array1[k++]); ui4->lineEdit_AIV33->setText(line_array1[k++]); ui4->lineEdit_AIV4->setText(line_array1[k++]); ui4->lineEdit_AIV44->setText(line_array1[k++]);
}
@My problemwas, if I stop the QProcess and disconnected the read_AV slot even it is displaying the text in lineEdit
but I want to develop an application like
If I click the stop button it will stop the Qprocess and stop the timer also and In LineEdit I want to display last values constantantly.
Is der any thing mis in my logic please guide me
-
the problem is in your read_AV() slot. You create on every call a new timer and overwrite the pointer to it. Thus at the end you have multiple timers triggering your updateText() slot.
-
so how can i overcome this problem?
sir I changed my code as shown below,
@
void Hmi1::on_start_AV_clicked()
{
QString program;
QStringList arguments;
program = "/home/IFSS/programs/VME/test";
timer = new QTimer(this);
process =new QProcess();
process->setReadChannel(QProcess::StandardOutput);
process->start(program,arguments);
connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(read_AV()));
}@
is this correct way or not??If I modify like this I am not able to connect the SLOT(updateText());
How can I change this code to requird way?
please
help me -
Create a single timer instance once, and re-use that. Your constructor would be a good candidate for a location to do that.
-
I am implemented the code as said by Andre,
even though it is not displayed the data -
or is there any other concept like creating new timer every time and close that timer? is it correct or not
-
Hi,
In your constructor HMI1 allocate the QProcess and the QTimer, don't start them!! but only connect the signals you need if wanted. Then in the Av_start simple start the QProcess and the QTimer.
Both the QProcess and the QTimer variables should be private members of your HMI1 class! That will fix a lot of issues here.
So, quick code example:
@
void HMI1::HMI1(QObject * parent)
: QObject(parent)
{
m_Timer = new QTimer(1000);
connect(timer, SIGNAL(timeout()), this, SLOT(updateText()));m_Process = new QProcess();
process->setReadChannel(QProcess::StandardOutput);
process->start(program,arguments);
connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(read_AV()));
}
and:
void HMI1::read_AV()
{
if (m_Timer != NULL)
m_Timer.start();
... // do the rest here
}
@ -
it is still unclear what you actually want to achieve.
I guess you want to display every line your QProcess' std. And each line you display has to be visible for at least 1 sec.
Am i correct? -
to raven-worx,
ya I want to display the data for every sec and also if I click stop button QProcess and timer both should stop thier process as well as timer
-
When the readyReadStandardOutput() signal is triggered it' may be that there are more/less than 1 new line available. Thus you probably wont display all the data. And it's definitely triggered more than every 1 sec.
Why don't you use a QTextEdit and append the text there?
If you have to stick to the QLineEdit (can just display single lines) you should write the stdout to a buffer, and read new lines when the timer (single instance) triggers.
(Actually the QProcess itself is already a buffer though) -
To Jeroentje@ho..
I tried as you said even though timer will not connect to that SLOT() -
acording to my application I should use only lineEdit to display the data
and I did nt understand
bq. If you have to stick to the QLineEdit (can just display single lines) you should write the stdout to a buffer, and read new lines when the timer (single instance) triggers.
can you explain me
-
here you go:
@
void Hmi1::on_start_AV_clicked()
{
QString program;
QStringList arguments;
program = "/home/IFSS/programs/VME/test";
process =new QProcess();
process->setReadChannel(QProcess::StandardOutput);
process->start(program,arguments);timer = new QTimer(this); timer->setInterval (1000); timer->setSingleShot (false); connect(timer, SIGNAL(timeout()), this, SLOT(read_AV())); timer->start(); }
void Hmi1::read_AV()
{
char buf[1024];
qint64 lineLength = process->readLine(buf, sizeof(buf));
if (lineLength > 0)
{
//set buf to your lineedit
}
}
@As i said, with your QLineEdit you can only display a single line of data. Unless you remove all linebreaks and display the whole data in one line.
Q(Plain)TextEdit would be more appropriate for this. -
thanks for your reply,,
I got one solution for this but once you check this one and said me is correct method or not?
code is as shown below
@
Hmi1::Hmi1(QWidget *parent) :
QWidget(parent),
ui4(new Ui::Hmi1)
{
ui4->setupUi(this);timer=new QTimer();
}@
start_button clicked
@
void Hmi1::on_start_AV_clicked()
{
QString program;
QStringList arguments;
process =new QProcess();
process->setReadChannel(QProcess::StandardOutput);
program = "/home/IFSS/programs/VME/test";
arguments<<"1";
process->start(program,arguments);
connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(read_AV()));
}
@
read_AV() slot
@
void Hmi1::read_AV()
{
QByteArray b1;
QStringList strLines;b1= process->readAllStandardOutput(); b1_size=b1_size+b1.length(); qDebug()<<QString::number(q++)<<" "<<QString::number(b1_size); strLines = QString(b1).split("\n"); foreach (line_array1[a++], strLines) {; }
if(timer!=NULL)
{
emit out(line_array1);
timer->start(1000);connect(this,SIGNAL(out(QString *)),this,SLOT(disp(QString *))); }
}
@
disp() slot
@
void Hmi1::disp(QString *line_array1)
{
ui4->lineEdit_AIV1->setText(line_array1[k++]);
ui4->lineEdit_AIV11->setText(line_array1[k++]);ui4->lineEdit_AIV2->setText(line_array1[k++]); ui4->lineEdit_AIV22->setText(line_array1[k++]); ui4->lineEdit_AIV3->setText(line_array1[k++]); ui4->lineEdit_AIV33->setText(line_array1[k++]); ui4->lineEdit_AIV4->setText(line_array1[k++]); ui4->lineEdit_AIV44->setText(line_array1[k++]);
}
@
& STOP button
@
void Hmi1::on_stop_AV_clicked()
{
if(timer->isActive())
{
connect(timer, SIGNAL(timeout()), this, SLOT(updateText()));
}
int n=process->pid();
QStringList arg;
arg<<QString::number(n);
QProcess *sh1=new QProcess();
sh1->start("kill",arg);process->closeReadChannel(QProcess::StandardOutput); process->close();
}
@@
void Hmi1::updateText()
{
timer->stop();
}
@by using this I am able to control the timer and Process