QThread::run update tableWidget in MainWindow



  • Greetings!

    I'm stuck with some (i guess) basic Qt stuff. I'm looking for the right and working way to update a tableWidget in QMainWindow from inside a QThread::run. I try to load multiple XML files from different sources (in this case FTP servers) at the same time, process them and update a tableWidget based on some of the results. The download part is working but i can't quite figure out how to access the tableWidet within a QThread subclass.

    class threadTest : public QThread
    {
        public:
            explicit threadTest(QStringList d);
            void run();
    
        private:
            QStringList data;
    };
    
    threadTest::threadTest(QStringList d) : data(d)
    {
    }
    
    void threadTest::run()
    {
        QString id = this->data.at(0);
    	
    	int rowCount = ui->tableWidget->rowCount();
    	for(int i = 0; i < rowCount; i++)
    	{
    		if(id == ui->tableWidget->item(i, 0)->text())
    		{
    			QTableWidgetItem *STATUS = new QTableWidgetItem ("Loading...");
    			ui->tableWidget->setItem(i, 1, STATUS);
    		}
    	}
    }
    

    Of course i can't access widgets like this, just to show what i want to accomplish. I did so far try a lot of things but so far i can't access the QMainWindow functions or widgets.

    Thanks!


  • Qt Champions 2016

    @qDebug
    Leaving aside you shouldn't be subclassing QThread for that, you can emit signals from the QThread::run override and connect those to your MainWindow or TableWidget or w/e.
    On a related note, even if you got a pointer to the main window or its ui, or any widget for that matter, the code shown is simply impossible to be run in another thread. QWidgets are neither reentrant nor thread-safe.



  • @kshegunov Thanks you!

    After adding a

    signals:
            void testMe(QString value);
    

    to my threadTest class

    and adding

    void threadTest ::testMe(QString value)
    {
        qDebug() << "testMe: " << value;
    }
    

    and connect it in my main class like this

    threadTest* dltest = new threadTest(dltestList);
    dltest->start();
    
    connect(dltest, SIGNAL(testMe(QString)), this, SLOT(setDatei(QString)));
    

    i get "QObject::connect: No such signal QThread::testMe(QString)". Did try to set dltest::testMe(QString) and a some other try and error attempts but unforgettability i can't figure out why this error keeps popping up.

    Thank You!


  • Qt Champions 2016

    @qDebug
    Signals are not supposed to be implemented by you, as moc generates a body for them. How does your code compile, you should be getting redefinition errors from the linker?

    i get "QObject::connect: No such signal QThread::testMe(QString)"

    Did you forget to add the Q_OBJECT macro to your QThread subclass?



  • I had to add Q_OBJECT and also delete my debug folder once, to get rid of a few link errors.

    Also got rid of the QThread subclassing, it is way easier to create a worker class and connect it through signals. There is really a lot of outdated example code out there.

    Thanks for your help!



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