Results 1 to 16 of 16

Thread: Scrolling tableview and updating via QThread

  1. #1
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Scrolling tableview and updating via QThread

    Hi all,

    I'm new to Qt having come from MFC. I have created a custom model to be used with a table view (it has to be quick). I have a seperate thread which updates the model and hence the table, problem is, if I scroll to the last item in the tableview in the thread, the whole gui thread is 'hogged' cannot do anything else? Is this a problem of updating a widget from within a seperate thread?

    This is how I scroll to last item added to tableview within the thread :

    Qt Code:
    1. QModelIndex index = treeModel->index(nCount-2,0);
    2. m_pCanList->scrollTo(index);
    To copy to clipboard, switch view to plain text mode 

    It is the scrollTo function which seems to 'hog' the main gui thread.

    I have got round this problem by using a timer event to update the table every millisecond, but thought the thread would be quicker.

    Any help, suggestions is much appreciated.

    Thanks,
    Steve

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Scrolling tableview and updating via QThread

    Don't scroll from the thread. Instead emit a signal and let the GUI thread scroll the table.
    Widgets must not be modified from other threads than the main thread.

    That is why the interface gets "hogged" .

    Regards

  3. #3
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Scrolling tableview and updating via QThread

    Thanks,

    Does this mean I need to connect a signal from the thread to some slot in the gui?

    For example within my thread I would have :

    Qt Code:
    1. signals:
    2. void scrolltable( QModelIndex index );
    To copy to clipboard, switch view to plain text mode 

    This function would emit a signal, such as:

    Qt Code:
    1. QModelIndex index = treeModel->index( nCount, 0 );
    2. emit scrolltable( index );
    To copy to clipboard, switch view to plain text mode 

    And within my main gui thread, I would have a slot as :

    Qt Code:
    1. public slots:
    2. void scrollthetable( QModelIndex index );
    To copy to clipboard, switch view to plain text mode 

    Which would scroll the table.


    How do I connect these signals, would it be something along the lines of ( this would be in main gui thread ) :

    Qt Code:
    1. connect( tableThread, SIGNAL(scrolltable(QModelIndex)), this,
    2. SLOT(scrollthetable(QModelIndex)) );
    To copy to clipboard, switch view to plain text mode 

    Thanks again,
    Steve

  4. #4
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Scrolling tableview and updating via QThread

    Yes, that's it!

    Regards

  5. #5
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Scrolling tableview and updating via QThread

    Thanks again,

    I did this but when I call emit from my thread the table still does not scroll?

    The code to scroll the table is just :

    Qt Code:
    1. void CanView::scrolltable( QModelIndex index )
    2. {
    3. ui.tableView->scrollTo( index );
    4. }
    To copy to clipboard, switch view to plain text mode 

    The model index is passed in from the thread as follows :

    Qt Code:
    1. QModelIndex index = m_ptreeModel->index( nCount - 2, 0 );
    2. emit scrolltable( index );
    To copy to clipboard, switch view to plain text mode 

    I'm at a loss as to why this does not work?

    Any help is appreciated.

    Regards,
    Steve

  6. #6
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Scrolling tableview and updating via QThread

    You said
    Qt Code:
    1. connect( tableThread, SIGNAL(scrolltable(QModelIndex)), this,SLOT(scrollthetable(QModelIndex)) );
    To copy to clipboard, switch view to plain text mode 

    but the slot is called scrolltable...
    Are you sure the connect is correct? Take a look at it again?
    If it is correct, could you look if the slot gets called?

    Regards

  7. #7
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Scrolling tableview and updating via QThread

    Sorry Marcel,

    I changed the slot and signal names to scrolltable and yes, the slot does indeed get called. In fact, no data is displayed in the tableview unless I click on it??

    Regards,
    Steve

  8. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Scrolling tableview and updating via QThread

    You shouldn't keep the reference to the model in the thread either. Maybe the model index is not valid. Instead passing a QModelIndex, pass an integer ( nCount - 2 ) if you can.

    Things should work fine, so the only question is if the model index passed was valid...

  9. #9
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Scrolling tableview and updating via QThread

    You were creating the model index on the stack. Emitting a signal from a thread will post an event in the thread in which the slot is implemented, it will not call the slot directly.

    So the model index you pass gets destroyed before the slot gets called.
    Either pass a pointer to a model index, which you will delete in the slot, either a integer and compute the model index in the GUI thread.

  10. #10
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Scrolling tableview and updating via QThread

    Thanks again Marcel,

    I have now done this :

    Qt Code:
    1. void CanView::scrolltable( int nCount )
    2. {
    3. QModelIndex index = m_pCanReadThread->m_ptreeModel->index( nCount, 0 );
    4. ui.tableView->scrollTo( index );
    5. }
    To copy to clipboard, switch view to plain text mode 

    But sadly again, the whole gui is 'hogged'?!

    Maybe my design is all wrong?

    Regards,
    Steve

  11. #11
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Scrolling tableview and updating via QThread

    Why are you holding the model in the thread? You should keep it in the GUI thread, and modify it via signals/slots.

    The thread should only do additional work, not hold interface elements.

    Regards

  12. #12
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Scrolling tableview and updating via QThread

    May I ask what is the thread actually doing? I'm not convinced that storing pointers to various GUI objects in a thread object is a good idea (even if you did not actually modify them).
    J-P Nurmi

  13. #13
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Scrolling tableview and updating via QThread

    How often the signal gets emitted anyway?
    If it gets really, really often, then you will kill the GUI event handler.
    Perhaps you should not emit the scroll signal if the specified index is already visible.

  14. #14
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Scrolling tableview and updating via QThread

    Hi,

    The signal will get emitted something like every millisecond.

    How do you work out if the specified index is already visible?

    The model is within the thread as the thread updates the model data, is this wrong? I just wanted the thread to read a signal from a car which gives data back and update the model, maybe I should just store the data in a buffer within the thread and send this back to the gui and let the gui update the model?

    Example of the run() method :
    Qt Code:
    1. while( nCount < 10000 )
    2. {
    3. m_ptreeModel->setCanData( QString("0xfea" ) );
    4. m_ptreeModel->setCanData( QString("----" ) );
    5. m_ptreeModel->setCanData( QString("222222222222" ) );
    6. QString strCount;
    7. strCount.sprintf( "%i", nCount );
    8. m_ptreeModel->setCanData( strCount );
    9. // QModelIndex index = m_ptreeModel->index( nCount , 0 );
    10. emit scrolltable( nCount );
    11. nCount++;
    12. }
    To copy to clipboard, switch view to plain text mode 

    As you can see, it doesn't do much at the moment...

    Thanks,
    Steve

  15. #15
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Scrolling tableview and updating via QThread

    Yes, it is wrong, especially because the signal is emitted 1000 times/second ( this means 1000 events posted each second in the GUI event handler ).

    I really don't know how to see if an item is visible, but you should take a look at the implementation of QTableView::scrollTo(). This should give you an idea.

    Once you solve this, you solve your problem.


    BTW: you shouldn't modify the model in the worker thread. Instead emit a signal with a structure with the data that need to be inserted.

  16. #16
    Join Date
    May 2007
    Posts
    301
    Thanks
    46
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Scrolling tableview and updating via QThread

    Thanks again,

    It is the scrollto function which seems to take ages, but I know of no other way of making sure the last item inserted is visible...

    I put all this stuff into a timer and it works fine, I guess for what I am trying to do, the timer event is the better option.

    Thanks for all your help

    Steve

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.