Results 1 to 5 of 5

Thread: Dynamic QSplitter

  1. #1
    Join Date
    Oct 2007
    Location
    Quebec, Canada
    Posts
    40
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Dynamic QSplitter

    Hi,

    I'm trying to familiarize myself with the splitter object and coded a little program to experiment with it. I have an object that triggers the split. Here's the header

    Qt Code:
    1. class WidgetSplitter
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. WidgetSplitter( QWidget* parent = 0 );
    7.  
    8. signals:
    9. void SplitVertical();
    10. void SplitHorizontal();
    11. void Unsplit();
    12.  
    13. protected slots:
    14. void SplitVerticalButtonClicked();
    15. void SplitHorizontalButtonClicked();
    16. void UnsplitButtonClicked();
    17.  
    18. };
    To copy to clipboard, switch view to plain text mode 

    I then derived QSplitter(MySplitter) to listen for signals WidgetSplitter is sending. The first time MySplitter receives a split signal, it sets the orientation and add another instance of WidgetSplitter. When orientation is set, as long as user click the split with the same orientation, MySplitter adds another instance of WidgetSplitter. When user wants to split in the other direction, MySplitter replaces the current WidgetSplitter instance by another MySplitter and add twos instances of WidgetSplitter. Unfortunately, when this occurs, it crashes.

    The only way I know to remove a widget from a QSplitter is by deleting it. I tried reparenting but with no success. To replace it, I first use indexOf to find position and the delete it. I create a new MySplitter, adds the two WidgetSplitter and insert it at the found index. Obviously this triggers a LayoutRequest and when splitter handles it, the previously deleted widget is still part of the layout and it crashes. I tried deleteLater because I thought it was safer but it's still crashing. Why QSplitter doesn't handle it correctly ?

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

    Default Re: Dynamic QSplitter

    Reparenting the widget should have done the trick. What did you reparent it to? And what does WidgetSplitter actually do? The header you posted is incorrect - it's not even a QObject. Did you mean it to be a widget or not?

  3. #3
    Join Date
    Oct 2007
    Location
    Quebec, Canada
    Posts
    40
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Dynamic QSplitter

    Yeah forgot the QWidget inheriting but it was in the code. Discovered the setParent for QObject and QWidget aren't the same so now the layout works ok but I can't destroy the instance of WidgetSplitter.

    Either normal delete and deleteLater crash the application in the next LayoutRequest handling by QSplitter. QWidget is destroyed but it is still in LayoutStruct in QSplitter and something weird, QSplitter::ChildEvent never gets called with QEvent::ChildRemoved event type. How come ? As I said, if I don't delete it, the layout works but I have a memory leak.

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

    Default Re: Dynamic QSplitter

    Could you attach the complete project code?

  5. #5
    Join Date
    Oct 2007
    Location
    Quebec, Canada
    Posts
    40
    Thanks
    4
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Dynamic QSplitter

    Here's the slots and spliting function :

    Qt Code:
    1. void TestSplitter::SplitVertical()
    2. {
    3. Split( sender(), Qt::Vertical );
    4. }
    5.  
    6. void TestSplitter::SplitHorizontal()
    7. {
    8. Split( sender(), Qt::Horizontal);
    9. }
    10.  
    11. void TestSplitter::Split( QObject* sender, Qt::Orientation splitOrientation )
    12. {
    13. // Get sender's parent(QSplitter object).
    14. QSplitter* splitter = qobject_cast<QSplitter*>( sender->parent() );
    15. if ( splitter )
    16. {
    17. // Check if splitter has already been splitted.
    18. QVariant splitted = splitter->property( "Splitted" );
    19. if ( !splitted.toBool() )
    20. {
    21. // Set orientation.
    22. splitter->setOrientation( splitOrientation );
    23.  
    24. // Add widget splitter object.
    25. WidgetSplitter* widgetSplitter = new WidgetSplitter( splitter );
    26. splitter->addWidget( widgetSplitter );
    27. widgetSplitter->show();
    28.  
    29. connect( widgetSplitter, SIGNAL(SplitVertical()), this, SLOT(SplitVertical()) );
    30. connect( widgetSplitter, SIGNAL(SplitHorizontal()), this, SLOT(SplitHorizontal()) );
    31. connect( widgetSplitter, SIGNAL(Unsplit()), this, SLOT(Unsplit()) );
    32.  
    33. splitter->setProperty( "Splitted", true );
    34. }
    35. else if ( splitOrientation == splitter->orientation() )
    36. {
    37. // Add widget splitter object.
    38. WidgetSplitter* widgetSplitter = new WidgetSplitter( splitter );
    39. splitter->addWidget( widgetSplitter );
    40. widgetSplitter->show();
    41.  
    42. connect( widgetSplitter, SIGNAL(SplitVertical()), this, SLOT(SplitVertical()) );
    43. connect( widgetSplitter, SIGNAL(SplitHorizontal()), this, SLOT(SplitHorizontal()) );
    44. connect( widgetSplitter, SIGNAL(Unsplit()), this, SLOT(Unsplit()) );
    45. }
    46. else
    47. {
    48. // We must destroy the current widget splitter and add replace it
    49. // with a QSplitter containing 2 widget splitter following
    50. // specified orientation.
    51.  
    52. QWidget* widget = static_cast<QWidget*>(sender);
    53.  
    54. // Get index of widget splitter.
    55. int index = splitter->indexOf( widget );
    56.  
    57. widget->setParent( NULL );
    58. widget->deleteLater();
    59.  
    60. QSplitter* newSplitter = new QSplitter();
    61. newSplitter->setOrientation( splitOrientation );
    62. newSplitter->setChildrenCollapsible( false );
    63.  
    64. WidgetSplitter* widgetSplitter = new WidgetSplitter( newSplitter );
    65. newSplitter->addWidget( widgetSplitter );
    66. widgetSplitter->show();
    67.  
    68. connect( widgetSplitter, SIGNAL(SplitVertical()), this, SLOT(SplitVertical()) );
    69. connect( widgetSplitter, SIGNAL(SplitHorizontal()), this, SLOT(SplitHorizontal()) );
    70. connect( widgetSplitter, SIGNAL(Unsplit()), this, SLOT(Unsplit()) );
    71.  
    72. widgetSplitter = new WidgetSplitter( newSplitter );
    73. newSplitter->addWidget( widgetSplitter );
    74. widgetSplitter->show();
    75.  
    76. connect( widgetSplitter, SIGNAL(SplitVertical()), this, SLOT(SplitVertical()) );
    77. connect( widgetSplitter, SIGNAL(SplitHorizontal()), this, SLOT(SplitHorizontal()) );
    78. connect( widgetSplitter, SIGNAL(Unsplit()), this, SLOT(Unsplit()) );
    79.  
    80. splitter->insertWidget( index, newSplitter );
    81. newSplitter->show();
    82. }
    83. }
    84. }
    To copy to clipboard, switch view to plain text mode 

    Keep in mind this is a test application and not production code.
    Last edited by EricF; 26th October 2007 at 18:39.

Similar Threads

  1. New to QSplitter
    By bruccutler in forum Qt Programming
    Replies: 6
    Last Post: 6th September 2007, 16:43
  2. How to set Widgets sizes with in QSplitter
    By rajeshs in forum Qt Programming
    Replies: 1
    Last Post: 29th June 2007, 07:38
  3. Switching static to dynamic ui loading
    By s_a_white in forum Newbie
    Replies: 4
    Last Post: 26th June 2006, 15:57
  4. qSplitter settings
    By ovidiu.sabou in forum Qt Tools
    Replies: 4
    Last Post: 14th March 2006, 18:24
  5. QSplitter
    By Solarity in forum Newbie
    Replies: 2
    Last Post: 10th February 2006, 17:05

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.