Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?
Forum Updated to NodeBB v4.3 + New Features

Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 3 Posters 2.2k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C cdwijs

    Hi All,

    I have made a custom widget. It is a QSplitter with a number of widgets in it. When I then place that custom widget into another QSplitter, I have to specify the parent, while I don't have to do that when I add a QTextBrowser. Why is this? How come a QTextBrowser automatically knows the parent, while my custom widget does not?

    Below are the relevant parts of the code:

    myHlayout = new QSplitter();
    rs232Rx = new RS232(myHlayout);
    rs232Tx = new RS232(myHlayout);
    myHlayout->setOrientation(Qt::Horizontal);
    myHlayout->addWidget(rs232Rx);
    myHlayout->addWidget(rs232Tx);
    

    class definition of RS232:

    class RS232 : public QWidget
    {
        Q_OBJECT
    public:
        RS232(QWidget *parent=0);
    public slots:
       <snip>
    signals:
       <snip>
       
    private:
       <snip>
    };
    

    Cheers,
    Cedric

    sierdzioS Offline
    sierdzioS Offline
    sierdzio
    Moderators
    wrote on last edited by
    #2

    @cdwijs said in Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?:

    rs232Rx = new RS232(myHlayout);
    rs232Tx = new RS232(myHlayout);

    Why do you specify the parent here? Calling just addWidget() is enough.

    (Z(:^

    C 1 Reply Last reply
    1
    • sierdzioS sierdzio

      @cdwijs said in Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?:

      rs232Rx = new RS232(myHlayout);
      rs232Tx = new RS232(myHlayout);

      Why do you specify the parent here? Calling just addWidget() is enough.

      C Offline
      C Offline
      cdwijs
      wrote on last edited by
      #3

      @sierdzio said in Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?:

      @cdwijs said in Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?:

      rs232Rx = new RS232(myHlayout);
      rs232Tx = new RS232(myHlayout);

      Why do you specify the parent here? Calling just addWidget() is enough.

      Thanks Sierdzio, I have just tried it, but this line causes the widget to float in it's own window:
      rs232Rx = new RS232();

      This line causes the widget to correctly place itself in the QSplitter.
      rs232Rx = new RS232(myHlayout);

      Maybe this is only true on my PC:
      Windows 7 enterprise SP1
      QT 5.10.1
      mingw53_32

      Cheers,
      Cedric

      1 Reply Last reply
      0
      • sierdzioS Offline
        sierdzioS Offline
        sierdzio
        Moderators
        wrote on last edited by
        #4

        @cdwijs said in Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?:

        Thanks Sierdzio, I have just tried it, but this line causes the widget to float in it's own window:

        That's because your splitter needs a parent.

        myHlayout = new QSplitter();

        (Z(:^

        C 1 Reply Last reply
        2
        • sierdzioS sierdzio

          @cdwijs said in Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?:

          Thanks Sierdzio, I have just tried it, but this line causes the widget to float in it's own window:

          That's because your splitter needs a parent.

          myHlayout = new QSplitter();

          C Offline
          C Offline
          cdwijs
          wrote on last edited by
          #5

          @sierdzio said in Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?:

          @cdwijs said in Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?:

          Thanks Sierdzio, I have just tried it, but this line causes the widget to float in it's own window:

          That's because your splitter needs a parent.

          myHlayout = new QSplitter();

          I'm not convinced :-) This yields 3 floating windows:

              myVlayout = new QSplitter(parent);
              myVlayout->setOrientation(Qt::Vertical);
              myRxLabel = new QLabel("Rx");
              myTxLabel = new QLabel("Tx");
              myClearBtn = new QPushButton("Clear");
              myLog = new QPlainTextEdit();
              myHlayout = new QSplitter(myVlayout);
              myHlayout->setOrientation(Qt::Horizontal);
              myHlayout->addWidget(myRxLabel);
              rs232Rx = new RS232();
              myHlayout->addWidget(rs232Rx);
              myHlayout->addWidget(myTxLabel);
              rs232Tx = new RS232();
              myHlayout->addWidget(rs232Tx);
              myHlayout->addWidget(myClearBtn);
              myVlayout->addWidget(myLog);
              myVlayout->addWidget(myHlayout);
              myVlayout->show();
          

          This yields the desired effect:

           myRxLabel = new QLabel("Rx");
              myTxLabel = new QLabel("Tx");
              myClearBtn = new QPushButton("Clear");
              myLog = new QPlainTextEdit();
              myHlayout = new QSplitter();
              myHlayout->setOrientation(Qt::Horizontal);
              myHlayout->addWidget(myRxLabel);
              rs232Rx = new RS232(myHlayout);
              myHlayout->addWidget(rs232Rx);
              myHlayout->addWidget(myTxLabel);
              rs232Tx = new RS232(myHlayout);
              myHlayout->addWidget(rs232Tx);
              myVlayout = new QSplitter();
              myVlayout->setOrientation(Qt::Vertical);
              myHlayout->addWidget(myClearBtn);
              myVlayout->addWidget(myLog);
              myVlayout->addWidget(myHlayout);
              myVlayout->show();
          

          I noticed this yields the 2 RS232 widgets to be displayed before the Rx and Tx labels, and finally the clear button:

          myRxLabel = new QLabel("Rx");
              myTxLabel = new QLabel("Tx");
              myClearBtn = new QPushButton("Clear");
              myLog = new QPlainTextEdit();
              myHlayout = new QSplitter();
              myHlayout->setOrientation(Qt::Horizontal);
              rs232Rx = new RS232(myHlayout);
              rs232Tx = new RS232(myHlayout);
              myHlayout->addWidget(myRxLabel);
              myHlayout->addWidget(rs232Rx);
              myHlayout->addWidget(myTxLabel);
              myHlayout->addWidget(rs232Tx);
              myVlayout = new QSplitter();
              myVlayout->setOrientation(Qt::Vertical);
              myHlayout->addWidget(myClearBtn);
              myVlayout->addWidget(myLog);
              myVlayout->addWidget(myHlayout);
              myVlayout->show();
          

          Cheers,
          Cedric

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #6

            Hi,

            Can you show the RS232 constructor content ?

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            C 1 Reply Last reply
            2
            • SGaistS SGaist

              Hi,

              Can you show the RS232 constructor content ?

              C Offline
              C Offline
              cdwijs
              wrote on last edited by
              #7

              @SGaist
              Sure:

              RS232::RS232(QWidget *parent)
              {
                  qDebug()<<Q_FUNC_INFO;
              #ifdef FAKE_MESSAGES
                  myTimer = new QTimer();
                  connect(myTimer,&QTimer::timeout,this,&RS232::slotTimer);
                  myTimer->setInterval(500);
                  myTimer->start();
              #endif
                  mySettingsDia = new SettingsDialog;
                  myRxQueue = new QQueue<unsigned char>;
                  myRxQueue->clear();
              
                  mySerialPort = new QSerialPort ;
                  myTxTimer = new QTimer();
                  myTxTimer->setSingleShot(true);
                  myRxTimer = new QTimer();
                  myRxTimer->setSingleShot(true);
              
                  myLabel = new QLabel("COM-");
              
                  mySettingsBtn = new QPushButton;
                  mySettingsBtn->setIcon(QIcon(":/images/wrench.png"));
                  mySettingsBtn->setToolTip("Settings");
              
                  myConnectBtn = new QPushButton;
                  myConnectBtn->setIcon(QIcon(":/images/disconnected.png"));
                  myConnectBtn->setToolTip("Connect");
              
                  const int LED_SIZE = 10;
                  myRxLED = new LedIndicator();
                  myRxLED->setLedSize(LED_SIZE);
                  myRxLED->setOnColor(Qt::green);
                  myRxLED->setToolTip("Rx");
              
                  myTxLED = new LedIndicator();
                  myTxLED->setLedSize(LED_SIZE);
                  myTxLED->setOnColor(Qt::green);
                  myTxLED->setToolTip("Tx");
              
                  myHlayout = new QSplitter();
                  myHlayout->setOrientation(Qt::Horizontal);
                  myHlayout->addWidget(myLabel);
                  myHlayout->addWidget(myTxLED);
                  myHlayout->addWidget(myRxLED);
                  myHlayout->addWidget(mySettingsBtn);
                  myHlayout->addWidget(myConnectBtn);
              
                  connect(mySettingsBtn,&QPushButton::clicked,this,&RS232::slotSettings);
                  connect(myConnectBtn,&QPushButton::clicked,this,&RS232::slotConnect);
                  connect(mySerialPort,&QSerialPort::readyRead,this,&RS232::slotRx);
                  connect(myRxTimer,&QTimer::timeout,this,slotRxTimer);
                  connect(myTxTimer,&QTimer::timeout,this,slotTxTimer);
                  myHlayout->setParent(parent);
                  myHlayout->show();
              }
              

              And the class:

              class RS232 : public QWidget
              {
                  Q_OBJECT
              public:
                  RS232(QWidget *parent=0);
              public slots:
                  slotSettings(bool clicked);
                  slotConnect(bool clicked);
                  slotDisconnect(bool clicked);
                  slotMessage(QString string);
                  slotRx();
                  slotRxTimer();
                  slotTxTimer();
              #ifdef FAKE_MESSAGES
                  slotTimer();
              #endif
              signals:
                  void sigOpenChanged(bool open);
                  void sigReceived(QString msg);
              private:
              #ifdef FAKE_MESSAGES
                  QTimer *myTimer;
              #endif
                  QTimer *myTxTimer;
                  QTimer *myRxTimer;
                  LedIndicator *myRxLED;
                  LedIndicator *myTxLED;
                  SettingsDialog *mySettingsDia;
                  QSplitter *myHlayout;
                  QLabel *myLabel;
                  QPushButton *mySettingsBtn;
                  QPushButton *myConnectBtn;
                  SettingsDialog::Settings *mySerSettings;
                  QSerialPort *mySerialPort;
                  QQueue<unsigned char> *myRxQueue;
              };
              
              sierdzioS 1 Reply Last reply
              0
              • C cdwijs

                @SGaist
                Sure:

                RS232::RS232(QWidget *parent)
                {
                    qDebug()<<Q_FUNC_INFO;
                #ifdef FAKE_MESSAGES
                    myTimer = new QTimer();
                    connect(myTimer,&QTimer::timeout,this,&RS232::slotTimer);
                    myTimer->setInterval(500);
                    myTimer->start();
                #endif
                    mySettingsDia = new SettingsDialog;
                    myRxQueue = new QQueue<unsigned char>;
                    myRxQueue->clear();
                
                    mySerialPort = new QSerialPort ;
                    myTxTimer = new QTimer();
                    myTxTimer->setSingleShot(true);
                    myRxTimer = new QTimer();
                    myRxTimer->setSingleShot(true);
                
                    myLabel = new QLabel("COM-");
                
                    mySettingsBtn = new QPushButton;
                    mySettingsBtn->setIcon(QIcon(":/images/wrench.png"));
                    mySettingsBtn->setToolTip("Settings");
                
                    myConnectBtn = new QPushButton;
                    myConnectBtn->setIcon(QIcon(":/images/disconnected.png"));
                    myConnectBtn->setToolTip("Connect");
                
                    const int LED_SIZE = 10;
                    myRxLED = new LedIndicator();
                    myRxLED->setLedSize(LED_SIZE);
                    myRxLED->setOnColor(Qt::green);
                    myRxLED->setToolTip("Rx");
                
                    myTxLED = new LedIndicator();
                    myTxLED->setLedSize(LED_SIZE);
                    myTxLED->setOnColor(Qt::green);
                    myTxLED->setToolTip("Tx");
                
                    myHlayout = new QSplitter();
                    myHlayout->setOrientation(Qt::Horizontal);
                    myHlayout->addWidget(myLabel);
                    myHlayout->addWidget(myTxLED);
                    myHlayout->addWidget(myRxLED);
                    myHlayout->addWidget(mySettingsBtn);
                    myHlayout->addWidget(myConnectBtn);
                
                    connect(mySettingsBtn,&QPushButton::clicked,this,&RS232::slotSettings);
                    connect(myConnectBtn,&QPushButton::clicked,this,&RS232::slotConnect);
                    connect(mySerialPort,&QSerialPort::readyRead,this,&RS232::slotRx);
                    connect(myRxTimer,&QTimer::timeout,this,slotRxTimer);
                    connect(myTxTimer,&QTimer::timeout,this,slotTxTimer);
                    myHlayout->setParent(parent);
                    myHlayout->show();
                }
                

                And the class:

                class RS232 : public QWidget
                {
                    Q_OBJECT
                public:
                    RS232(QWidget *parent=0);
                public slots:
                    slotSettings(bool clicked);
                    slotConnect(bool clicked);
                    slotDisconnect(bool clicked);
                    slotMessage(QString string);
                    slotRx();
                    slotRxTimer();
                    slotTxTimer();
                #ifdef FAKE_MESSAGES
                    slotTimer();
                #endif
                signals:
                    void sigOpenChanged(bool open);
                    void sigReceived(QString msg);
                private:
                #ifdef FAKE_MESSAGES
                    QTimer *myTimer;
                #endif
                    QTimer *myTxTimer;
                    QTimer *myRxTimer;
                    LedIndicator *myRxLED;
                    LedIndicator *myTxLED;
                    SettingsDialog *mySettingsDia;
                    QSplitter *myHlayout;
                    QLabel *myLabel;
                    QPushButton *mySettingsBtn;
                    QPushButton *myConnectBtn;
                    SettingsDialog::Settings *mySerSettings;
                    QSerialPort *mySerialPort;
                    QQueue<unsigned char> *myRxQueue;
                };
                
                sierdzioS Offline
                sierdzioS Offline
                sierdzio
                Moderators
                wrote on last edited by
                #8

                @cdwijs said in Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?:

                RS232::RS232(QWidget *parent)

                You are not initializing the parent class! Should be:

                RS232::RS232(QWidget *parent) : QWidget(parent)
                

                That should fix your problems. @SGaist well done :-)

                (Z(:^

                1 Reply Last reply
                2
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #9

                  Also, you are using QSplitter like a layout manager which it is not. It's currently "floating" in RS232. Either put the splitter in a QVBox/HBoxLayout in RS232 (and other widgets you are using) or, depending on what you want to do, use layouts in place of QSplitter.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  C 1 Reply Last reply
                  2
                  • SGaistS SGaist

                    Also, you are using QSplitter like a layout manager which it is not. It's currently "floating" in RS232. Either put the splitter in a QVBox/HBoxLayout in RS232 (and other widgets you are using) or, depending on what you want to do, use layouts in place of QSplitter.

                    C Offline
                    C Offline
                    cdwijs
                    wrote on last edited by
                    #10

                    @SGaist said in Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?:

                    Also, you are using QSplitter like a layout manager which it is not. It's currently "floating" in RS232. Either put the splitter in a QVBox/HBoxLayout in RS232 (and other widgets you are using) or, depending on what you want to do, use layouts in place of QSplitter.

                    I have made a new program that uses 3 layers (toplevel,midlevel,fourbuttons) of widgets:
                    https://github.com/cdwijs/qt-experiments/tree/master/untitled2
                    This works as expected, I see one window with groups of groups of buttons.

                    Is this the correct way of doing things?

                    Cheers,
                    Cedric

                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #11

                      It depends, why do you need. Do you really have any use for all these QSplitter ?

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      C 1 Reply Last reply
                      0
                      • SGaistS SGaist

                        It depends, why do you need. Do you really have any use for all these QSplitter ?

                        C Offline
                        C Offline
                        cdwijs
                        wrote on last edited by
                        #12

                        @SGaist said in Parenting: why is a custom widget placed in a QSplitter not automatically a child of that splitter?:

                        It depends, why do you need. Do you really have any use for all these QSplitter ?

                        The splitters make sure I never have to alter the program if the end user wants to change some cosmetic aspect. I agree however that this program overuses Qsplitters.

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved