Results 1 to 8 of 8

Thread: QTreeWidget not updating content...

  1. #1
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default QTreeWidget not updating content...

    Hi,

    I have a QTreeWidget with several items, and I have a timer running to dynamically change the text of the tree item each few seconds.

    I then use QTreeWidgetItem::setText trying to update the content, but nothing changes in the tree display, unless I click a button on the item or change the selection, or cover and window on the tree and then expose it...

    How can I force the tree to repaint? I call QTreeWidget::repaint and it crashes, I also try QTreeWidget::update but nothing work, I also use QApplication::sendEvent( myTree, ...), and it does not work either....

    Any comments?

    Thanks

  2. #2
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    258
    Thanks
    22
    Thanked 19 Times in 16 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: QTreeWidget not updating content...

    Try out this piece of code. For me it works without userinteraction.

    Qt Code:
    1. #include <QApplication>
    2. #include <QtGui>
    3.  
    4. class MainWindow : public QMainWindow
    5. {
    6. Q_OBJECT
    7. public:
    8. MainWindow(QWidget* parent=0) : QMainWindow(parent)
    9. {
    10. treeWidget = new QTreeWidget;
    11. for (int i = 0; i < 50; ++i)
    12. treeWidget->addTopLevelItem(new QTreeWidgetItem);
    13. doSomething();
    14. setCentralWidget(treeWidget);
    15. startTimer(2000);
    16. }
    17.  
    18. void timerEvent(QTimerEvent* ) { doSomething(); }
    19. private:
    20. QTreeWidget* treeWidget;
    21. private slots:
    22. void doSomething()
    23. {
    24. static int x = 0;
    25. int i = 0;
    26. while(*iter) {
    27. (*iter)->setText(0, QString("row:%1 - modified: %2 times").arg(i).arg(x));
    28. ++i; ++iter;
    29. }
    30. x++;
    31. }
    32. };
    33.  
    34. #include "main.moc"
    35. int main(int argc, char* argv[])
    36. {
    37. QApplication app(argc, argv);
    38. MainWindow mw;
    39. mw.show();
    40. return app.exec();
    41. }
    To copy to clipboard, switch view to plain text mode 

  3. #3
    Join Date
    Dec 2006
    Posts
    426
    Thanks
    8
    Thanked 18 Times in 17 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QTreeWidget not updating content...

    I was doing the update in a thread, in my app, the fields need to be recalculated, which take several seconds. I hope to use thread so the GUI won't freeze. But then it does not update...

    Qt Code:
    1. #include <QApplication>
    2. #include <QThread>
    3. #include <QtGui>
    4.  
    5. #include <iostream>
    6.  
    7. class MyThread : public QThread {
    8.  
    9. public:
    10. MyThread( QTreeWidget* w ) : treeWidget( w ) {}
    11.  
    12. protected:
    13. void run()
    14. {
    15. std::cout << "MyThread::run called" << std::endl;
    16.  
    17. static int x = 0;
    18. int i = 0;
    19. while(*iter) {
    20. (*iter)->setText(0, QString("row:%1 - modified: %2 times").arg(i).arg(x));
    21. ++i; ++iter;
    22. }
    23. x++;
    24. }
    25.  
    26. private:
    27.  
    28. QTreeWidget* treeWidget;
    29.  
    30. };
    31.  
    32. class MainWindow : public QMainWindow
    33. {
    34. Q_OBJECT
    35. public:
    36. MainWindow(QWidget* parent=0) : QMainWindow(parent)
    37. {
    38. treeWidget = new QTreeWidget;
    39. thread = new MyThread( treeWidget );
    40. for (int i = 0; i < 50; ++i)
    41. treeWidget->addTopLevelItem(new QTreeWidgetItem);
    42. setCentralWidget(treeWidget);
    43. QMainWindow::startTimer(2000);
    44. }
    45.  
    46. void timerEvent(QTimerEvent* ) {
    47. if ( !thread->isRunning() ) thread->start();
    48. }
    49. private:
    50. QTreeWidget* treeWidget;
    51. QThread* thread;
    52. };
    53.  
    54. #include "main.moc"
    55. int main(int argc, char* argv[])
    56. {
    57. QApplication app(argc, argv);
    58. MainWindow mw;
    59. mw.show();
    60. return app.exec();
    61. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,017 Times in 4,793 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QTreeWidget not updating content...

    You can't update widgets from within threads. Widgets are not thread safe nor even reentrant.

  5. #5
    Join Date
    Aug 2007
    Posts
    166
    Thanks
    16
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTreeWidget not updating content...

    The only way to update the GUI interface throuth non-gui thread is to use signals and slots connections, else it can even crash.

    Edit: Oops wysota was faster than me. :P

  6. #6
    Join Date
    Aug 2009
    Posts
    1
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QTreeWidget not updating content...

    I am dealing with a similar problem, where I try to update my QTreeWidegetItem text (I have only one column) through a signal slot in my QTreeWidget class.

    My display for each item is like : <variable> == <value> like "abc = 1 or abc == 0".

    The above tree item value gets changed in my signal slot (e.g when I drag a horizontal slider in my widget) and I use setItemDelegate class method paint() to display the same.
    This paint functions rightly calculates the string like "abc == 1" for any position of the slider.

    1. Now how can I call the ItemDelegate:aint() from my Slot function (when I change the slider position ) ? My purpose is to refresh value in the new slider position. As usual If the hides and comes back into my tree view it shows the correct string.

    2. I have tried calling setText(0, str) where str = "abc == 1" but this is not OK as I want to customize my display inside paint() like color/font of the value part etc.


    Any idea would be of great help for me.

  7. #7
    Join Date
    Aug 2010
    Posts
    1
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QTreeWidget not updating content...

    so what is the right way to do this? I have the same problem as the original poster where some calculations take a long time and I can't hold up the GUI during that time. I tried having the non-gui thread call functions in the gui thread that do the updating, but that seems to give inconsistent results (sometimes crash, sometimes not update everything, sometimes work fine.) I didn't understand the explanations of how to solve the problem with slots/signals.

    I'm trying having my non-gui thread which does the calculations update variables in the gui thread, then using a timeout in the gui thread to periodically check the variables for changes and update accordingly. I'm not even sure if this solution works...and...I'm guessing there is a better way...

  8. #8
    Join Date
    Aug 2007
    Posts
    166
    Thanks
    16
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTreeWidget not updating content...

    Using timer to check your Thread's class for value updates is fine if you are pulling out updates very fast. The only thing that may fail to you now is improper synchronization. You must use QMutex or QReadWriteLock to lock the memory on the places you update and access the shared data. For example if you have some getValue() method in your thread's class, that you call using the timer from your gui thread. You should lock it like that:
    Qt Code:
    1. Mydata MyThread::getValue()
    2. {
    3. mutex.lock();
    4. MyData data = m_calculatedData; // Copy the shared data
    5. mutex.unlock();
    6.  
    7. return data;
    8. }
    To copy to clipboard, switch view to plain text mode 

    Same goes for the part where you update m_calculatedData (in your run() method perhaps). I.e. whatever you are updating or copying data from m_calculatedData using different threads you should lock it. There is a lot of synchronization classes and helpers in Qt like QMutexLocker, QReadWriteLock, QSemaphore, QWaitCondition. The mutex will do the job for almost every task but depending on the situation other locker mechanisms might be better. You have to spend some time in reading the Qt documentation.

Similar Threads

  1. resizing a QTreeWidget
    By drhex in forum Qt Programming
    Replies: 6
    Last Post: 27th October 2006, 22:32

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.