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 Offline
    C Offline
    cdwijs
    wrote on last edited by
    #1

    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 1 Reply Last reply
    0
    • 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