Results 1 to 4 of 4

Thread: Why does a QSpliter reverse the order of QFrames?

  1. #1
    Join Date
    Jan 2013
    Posts
    25
    Qt products
    Qt4
    Platforms
    Windows

    Default Why does a QSpliter reverse the order of QFrames?

    Hey all, i have a question regarding the use of a QSplitter.

    I have a form with 2 frames in it right above each other. Now the content of these frames are a bit dynamic and for testing I use a Python call to read the children which gives me something like:

    <QWidget>
    <Frame_A>
    <Frame_B>
    </QWidget>

    Now for usability reasons, I had to make these frames scalable as the content in the top frame can be bigger than the bottom. So i added a QSplitter between these frames.



    But for some reason, when the splitter is added, the order of the frames is suddenly reversed and gives me:

    <QWidget>
    <Frame_B>
    <Frame_A>
    </QWidget>

    The .ui file seems to be correct and indeed gives me A on top and B below it.

    If i turn the frames around (so Frame_A is on the bottom), my result is correct again (but reversed as Frame_B is on the top now). I tried to replicate it with a very barebones form (no other logic assigned to it) and i get the same results. Is this a Qt bug or am i missing something?


    Other things i tried and did not work:

    - Changing the Object names of the frames (alphabetically)
    - Removing the frames and readding them in the order i wanted
    - Removing the frames and readding them in the reversed order i wanted
    - Editting the XML file manually and changing the order

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Why does a QSpliter reverse the order of QFrames?

    Is this a Qt bug or am i missing something?
    No, and probably.

    A verbal description of the problem isn't very useful in helping us understand what is wrong. You need to post some code that demonstrates how you are creating the splitter and adding the child frames to it, as well as what you are doing to cause the order of the frames to become reversed.

    Your widget hierarchy -should- look like this:

    Qt Code:
    1. Widget
    2. Splitter
    3. Frame A
    4. Frame B
    To copy to clipboard, switch view to plain text mode 

    From your description, it isn't clear how you are creating the splitter or even if it is in the hierarchy defined by the parent widget at all.
    Last edited by d_stranz; 6th November 2019 at 18:51.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Jan 2013
    Posts
    25
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Why does a QSpliter reverse the order of QFrames?

    I do everything in the Qt Designer (Qt Creator 4.1.0, Based on Qt 5.6.2). For testing this, i made a very simple form with just the 3 elements (2 Qframes with a QSplitter) and everything looks fine in here (the XML/.ui file).



    I made a bit of code to read out all the topLevelWidgets in of my form and dump them into a txt file to see the result. This is similar to how I use it in my application.
    That code is:

    Qt Code:
    1. static void dumpWidgetRecursion(QTextStream &str, const QWidget *w, int depth = 0)
    2. {
    3. if (depth)
    4. str << QString(depth * 2, QLatin1Char(' '));
    5. const QRect geom = w->geometry();
    6. str << '"' << w->metaObject()->className() << "\"/\"" << w->objectName() << "\" "
    7. << geom
    8. << (w->isVisible() ? "[visible] " : "[hidden] ");
    9. if (w->testAttribute(Qt::WA_Mapped))
    10. str << "[mapped] ";
    11. str << '\n';
    12. foreach (QObject *c, w->children()) {
    13. if (c->isWidgetType())
    14. dumpWidgetRecursion(str, (const QWidget *)(c), depth + 1);
    15. }
    16. }
    17.  
    18. static void dumpAllWidgets()
    19. {
    20. QTextStream str(&d);
    21. std::ofstream myfile("dumpallwidgets.txt");
    22.  
    23. str << "### QWidgets:\n";
    24. foreach (const QWidget *w, QApplication::topLevelWidgets())
    25. dumpWidgetRecursion(str, w);
    26. myfile << d.toStdString();
    27. }
    To copy to clipboard, switch view to plain text mode 

    which gives me a result of:

    Qt Code:
    1. "QSplitter"/"splitter" 571x241+140+70[visible]
    2. "QFrame"/"frame_B" 571x118+0+123[visible]
    3. "QFrame"/"frame_A" 571x118+0+0[visible]
    4. "QSplitterHandle"/"qt_splithandle_" 100x30+0+0[hidden]
    5. "QSplitterHandle"/"qt_splithandle_" 571x5+0+118[visible]
    To copy to clipboard, switch view to plain text mode 

    Notice how Frame_B is above Frame_A. This is causing me issues that i don't have if the splitter is not present.
    Last edited by Nyte; 7th November 2019 at 08:21.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Why does a QSpliter reverse the order of QFrames?

    From the docs for QObject::children():

    const QObjectList &QObject::children() const

    Returns a list of child objects. The QObjectList class is defined in the <QObject> header file as the following:

    typedef QList<QObject*> QObjectList;

    The first child added is the first object in the list and the last child added is the last object in the list, i.e. new children are appended at the end.

    Note that the list order changes when QWidget children are raised or lowered. A widget that is raised becomes the last object in the list, and a widget that is lowered becomes the first object in the list.
    See the last sentence. The order is not guaranteed to be static; it will change based on UI activity. Even if you don't do anything, simply calling show() on this widget may result in frame_b being activated and raised. You could experiment with this by clicking first in frame A and dumping, then in frame B and dumping to see if you get the same order.

    In addition, you cannot be guaranteed that the Qt runtime will create and add the widgets in the same order as the hierarchy defined in the UI file. The hierarchy on-scren will be correct, but the ordering of the children may not be the same.

    If you actually populated your frames with different child widgets, you would see that the on-screen order of the frames within the splitter is constant (unless you programmatically change them), it is only the order in the list returned by the children() call that might change.

    If you are relying on the order of the frames for some program need, then I would suggest you either create them programmatically (i.e., not using Qt Designer) and store their pointers in a separate vector / list in the order you want them, or use Qt Designer, but retrieve the frame pointers at runtime by object name (QObject::findChild()) in the order you want ("Frame_A", "Frame_B") and store those i a vector.
    Last edited by d_stranz; 7th November 2019 at 19:54.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Replies: 1
    Last Post: 17th April 2012, 16:53
  2. XML and reverse geocoding
    By seanasl in forum Qt Quick
    Replies: 0
    Last Post: 24th January 2012, 09:46
  3. Handling z order of QLabels in QFrames
    By [?]jNs in forum Newbie
    Replies: 1
    Last Post: 28th July 2011, 18:33
  4. Reverse Order on QStringList slow...?
    By patrik08 in forum Qt Programming
    Replies: 24
    Last Post: 21st February 2007, 10:32
  5. How setEnabled() works on QFrames.
    By Doug Broadwell in forum Newbie
    Replies: 4
    Last Post: 18th October 2006, 20:55

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.