Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Write text file in Qthread



  • Hello, thanks to Qt Forum I currently finish my GUI work. but the professor asked me to add a writing function so that I can plot the time-location graph.
    the purpose of the writing function is to write the current location of the motor and time in the textfile repeatly.
    My GUI displays the location in the QTextBrowser using QThread. Here are my codes

    Position.h

    class Position : public QObject
    {
        Q_OBJECT;
    public:
        Position();
        ~Position();
        void startThread1(MDCE* pcom, QTextBrowser* browser);
        void measureLocation1(MDCE* pcom);
        void stopMeasure();
    private:
        QThread* thread1;
        QElapsedTimer* timer;
    
    signals:
        void location_changed1(QString location);
    };
    

    Position.cpp

    //Start the thread that displays built-in position value of motor
    void Position::startThread1(MDCE* pcom, QTextBrowser* browser)
    {
        connect(this, &Position::location_changed1, browser, &QTextBrowser::setText);
        thread1 = QThread::create(std::bind(&Position::measureLocation1,this, pcom));
        thread1->start();
    }
    
    void Position::measureLocation1(MDCE* pcom)
    {
        double location;
        char record[] = "X_enc_pos";
    
        // From now, this is my modification of code
        QFile file("C:/Users/Sonic/experiment.txt");
        if (!file.open(QFile::WriteOnly | QFile::Text))
        {
            return;
        }
        QTextStream out(&file);
        timer->start();
        //
        while (1)
        {
            GetVarN(record, &location, 0, pcom); //this function returns double value to location.
            out << timer->elapsed() << " " << location<<"\n"; // write time and location value to experiment.txt
            emit location_changed1(QString::number(location));
            if (QThread::currentThread()->isInterruptionRequested()) return;
        }
    }
    

    and finally, in mainwindow.cpp

    connect(ui->btnData, SIGNAL(clicked()), this, SLOT(data()));
    
    void MainWindow::data()
    {
        thread->startThread1(motor, ui->statusHeader);
    }
    

    When I run the codes without addition, It works properly-displays the location value to statusheader, but with addition, It doesn't work.

    It seems to have a problem in while loop in position.cpp because I checked the experiment.txt file is created.

    Can you do me a favor?


  • Lifetime Qt Champion

    Hi,

    And what exactly is your issue ?

    I hope you are giving due credit to the people helping you when returning your assignments ;-)



  • @SGaist said in Write text file in Qthread:

    I hope you are giving due credit to the people helping you when returning your assignments ;-)

    LOL!



  • @SGaist
    Hi, My issue is when I put the opening and writing file code, the while loop doesn't run.
    My original code is like below

    void Position::measureLocation1(MDCE* pcom)
    {
        double location;
        char record[] = "X_enc_pos";
        while (1)
        {
            GetVarN(record, &location, 0, pcom); //this function returns double value to location.
            emit location_changed1(QString::number(location));
            if (QThread::currentThread()->isInterruptionRequested()) return;
        }
    }
    

    It emits signals repeatedly in the thread properly.

    I expect the code runs through the following process when I changed codes

    create experiment.txt
    in while loop
    {
    write elapsed time and the value of the position to experiment.txt
    emit signal
    }
    when I give interruption, stop the while loop.

    I already mentioned to the professor that thanks to QT forum, I found breakthrough in my GUI work :) I really appreciate it.


  • Moderators

    @H-dragon
    so, have you tried this

    out << timer->elapsed() << " " << location<<"\n";

    without thread and while loop and everything?
    depending on what it is, QTextStream may not be able to interpret that variables to write them to file



  • @J-Hilk
    Yes, I run out << timer->elapsed() << " " << location<<"\n"; in the following 4 situations.

    1. run in mainwindow.cpp just once -> run properly
    2. use QTextStream as parameter -> compile error
    void MainWindow::data()
    {
        QFile file("C:/Users/Sonic/experiment.txt");
        if (!file.open(QFile::WriteOnly | QFile::Text))
        {
            return;
        }
        QTextStream out(&file);
        thread->startThread1(motor, ui->statusHeader, out); ///QTextStream as parameter
    }
    
    1. run in the thread, but not in while loop -> GUI terminate. It doesn't work.
    2. run in while loop -> my goal, but doesn't work too

  • Moderators

    @H-dragon

    If it works without the thread and the while loop, then my guess is, you're overwhelming the OS's file IO system or QTextStream. The write attempt probably happens a couple hundred times per second.

    Try to explicitly flush, after writing

    GetVarN(record, &location, 0, pcom); //this function returns double value to location.
            out << timer->elapsed() << " " << location<<"\n"; // write time and location value to experiment.txt
            out.flush();
            emit location_changed1(QString::number(location));
            if (QThread::currentThread()->isInterruptionRequested()) return;
    


  • @J-Hilk
    Thank you for suggestion. but it doesn't work. Shouldn't I use QTextsteram in the thread?


  • Moderators

    @H-dragon in the case above, out is a QTextStream object, is it not ? (it has flush() as well)



  • @J-Hilk
    yes. out is QTextStream object as you said. there is not an error but when I activate the function, my GUI just terminate



  • Check with your debugger if the QTextBrowser is not accessed from the second thread. All GUI actions must be performed from the main thread. it's forbidden to access GUI from another thread.


Log in to reply