[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


  • Moderators

    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
    }
    @


  • Moderators

    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


  • Moderators

    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


  • Moderators

    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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.