0

It seems that when i place 2 frames in a QSplitter, the splitter seems to give a reversed index of the frames.

For example:

enter image description here

I place 2 frames (frame_A and frame_B) in a vertical splitter. Frame_B is created first and then Frame_A. When i do NOT use a QSplitter, Frame_A is detected first.

<QSplitter>
  <frame_B>
  <frame_A>
<QSplitter>

How do I make sure that the top frame is created first, instead of the bottom?

Things i tried

  • Changing the names of the frames (alphabetically). Did not work
  • Removing the frames and re-adding them in the order I wanted. Did not work.
  • Removing the frames and re-adding them in the reversed order I wanted. Did not work

Something that did work is placing the top list on the bottom and vice versa before adding the Splitter and this indeed worked, but this makes the form reversed.

Minimum Reproducible Example

Splitter.ui file

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <widget class="QSplitter" name="splitter">
   <property name="geometry">
    <rect>
     <x>45</x>
     <y>40</y>
     <width>261</width>
     <height>166</height>
    </rect>
   </property>
   <property name="orientation">
    <enum>Qt::Vertical</enum>
   </property>
   <widget class="QFrame" name="frame_A">
    <property name="frameShape">
     <enum>QFrame::StyledPanel</enum>
    </property>
    <property name="frameShadow">
     <enum>QFrame::Raised</enum>
    </property>
   </widget>
   <widget class="QFrame" name="frame_B">
    <property name="frameShape">
     <enum>QFrame::StyledPanel</enum>
    </property>
    <property name="frameShadow">
     <enum>QFrame::Raised</enum>
    </property>
   </widget>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

To find the order, i use the following code

static void dumpWidgetRecursion(QTextStream &str, const QWidget *w, int depth = 0)
{
    if (depth)
        str << QString(depth * 2, QLatin1Char(' '));
    const QRect geom = w->geometry();
    str << '"' << w->metaObject()->className() << "\"/\"" << w->objectName() << "\" "
        << geom
        << (w->isVisible() ? "[visible] " : "[hidden] ");
    if (w->testAttribute(Qt::WA_Mapped))
        str << "[mapped] ";
    str << '\n';
    foreach (QObject *c, w->children()) {
        if (c->isWidgetType())
             dumpWidgetRecursion(str, (const QWidget *)(c), depth + 1);
    }
}

static void dumpAllWidgets()
{
    QString d;
    QTextStream str(&d);
    std::ofstream myfile("dumpallwidgets.txt");

    str << "### QWidgets:\n";
    foreach (const QWidget *w, QApplication::topLevelWidgets())
         dumpWidgetRecursion(str, w);
    myfile << d.toStdString();
}

This will give me the result of:

"QSplitter"/"splitter" 571x241+140+70[visible] 
          "QFrame"/"frame_B" 571x118+0+123[visible] 
          "QFrame"/"frame_A" 571x118+0+0[visible] 
          "QSplitterHandle"/"qt_splithandle_" 100x30+0+0[hidden] 
          "QSplitterHandle"/"qt_splithandle_" 571x5+0+118[visible]

As you can see, Frame_B comes before Frame_A, which is not the result i expect.

DennisW
  • 153
  • 1
  • 6
  • provide a [mre] – eyllanesc Nov 04 '19 at 15:36
  • The order of the items returned by [QObject::children](https://doc.qt.io/qt-5/qobject.html#children) isn't static, so your code doesn't prove anything. The order of the widgets in the splitter should be verified using [QSplitter::widget](https://doc.qt.io/qt-5/qsplitter.html#widget). This proves that the frames are in the expected order: i.e. `frame_A` is at index `0`, which matches what is shown in the ui file. – ekhumoro Nov 05 '19 at 00:56

0 Answers0