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. Designing a "composite widget"
Forum Updated to NodeBB v4.3 + New Features

Designing a "composite widget"

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 2.4k Views 2 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.
  • J Offline
    J Offline
    JonB
    wrote on 9 Jan 2018, 16:24 last edited by JonB 1 Sept 2018, 16:24
    #1

    This is my first foray into designing a UI element with Qt, so I'd appreciate a pointer as to whether I'm going in the right direction.

    I use Qt 5.7, but from Python/PyQt, not C++. No QML/Quick Controls.

    The code base currently has a number of plain QLineEdit controls for entering dates. There is validation checking, but no interface other than typing into the widget.

    I wish to implement (what I call) a "composite widget":

    • A QLineEdit, like the existing one. (I wish to preserve this to allow users to just do in-line editing of date if they so wish.)
    • A "..." QPushButton to the right of the line. When clicked, this will bring up a small modal dialog containing a QCalendarWidget. This allows the user to pick a date. When picked, the dialog will close and the date will be copied back to the line edit.
    • The two widgets (presumably) to be enclosed in a QHBoxLayout, so that they appear side-by-side.

    So I assume I should be designing: a top-level widget, which holds the layout, which holds the QLineEdit followed by the QPushButton. Like (approximate syntax):

    class JDateLineEdit(QWidget):
        def __init__(self):
            super().__init__()
    
            self.lineEdit = QLineEdit()
            self.button = QPushButton("...")
            layout = QHBoxLayout()
            layout.addWidget(self.lineEdit)
            layout.addWidget(self.button)
            self.setLayout(layout)
    
            self.button.clicked.connect(self.datePicker)
    
        def datePicker():
            # 1. Create Dialog, containing QCalendarWidget.
            # 2. Copy currently selected date to be initial date on calendar.
            # 3. Show modal dialog, allow user interaction.
            # 4. Copy selected date back to QLineEdit.
    

    Does this look about right? In particular, since my "composite widget" is composed of a QHBoxLayout which then holds 2 QWidgets, I see it that it must derive from generic QWidget, rather than, say, directly from QLineEdit?

    K 1 Reply Last reply 9 Jan 2018, 18:06
    0
    • J Offline
      J Offline
      JonB
      wrote on 11 Jan 2018, 12:31 last edited by JonB 1 Nov 2018, 12:32
      #5

      This discussion about "composite widgets" in general has been useful.

      However, in my case of wanting to design "a line edit with a calendar popup", specifically, don't do this! I was fooled by the picture at http://doc.qt.io/qt-5/qdateedit.html#details showing it with a line-only interface. I have only just discovered that QDateEdit has http://doc.qt.io/qt-5/qdatetimeedit.html#calendarPopup-prop (would be nice if docs showed a pic using that!), which does exactly what I had in mind.

      1 Reply Last reply
      1
      • J JonB
        9 Jan 2018, 16:24

        This is my first foray into designing a UI element with Qt, so I'd appreciate a pointer as to whether I'm going in the right direction.

        I use Qt 5.7, but from Python/PyQt, not C++. No QML/Quick Controls.

        The code base currently has a number of plain QLineEdit controls for entering dates. There is validation checking, but no interface other than typing into the widget.

        I wish to implement (what I call) a "composite widget":

        • A QLineEdit, like the existing one. (I wish to preserve this to allow users to just do in-line editing of date if they so wish.)
        • A "..." QPushButton to the right of the line. When clicked, this will bring up a small modal dialog containing a QCalendarWidget. This allows the user to pick a date. When picked, the dialog will close and the date will be copied back to the line edit.
        • The two widgets (presumably) to be enclosed in a QHBoxLayout, so that they appear side-by-side.

        So I assume I should be designing: a top-level widget, which holds the layout, which holds the QLineEdit followed by the QPushButton. Like (approximate syntax):

        class JDateLineEdit(QWidget):
            def __init__(self):
                super().__init__()
        
                self.lineEdit = QLineEdit()
                self.button = QPushButton("...")
                layout = QHBoxLayout()
                layout.addWidget(self.lineEdit)
                layout.addWidget(self.button)
                self.setLayout(layout)
        
                self.button.clicked.connect(self.datePicker)
        
            def datePicker():
                # 1. Create Dialog, containing QCalendarWidget.
                # 2. Copy currently selected date to be initial date on calendar.
                # 3. Show modal dialog, allow user interaction.
                # 4. Copy selected date back to QLineEdit.
        

        Does this look about right? In particular, since my "composite widget" is composed of a QHBoxLayout which then holds 2 QWidgets, I see it that it must derive from generic QWidget, rather than, say, directly from QLineEdit?

        K Offline
        K Offline
        kshegunov
        Moderators
        wrote on 9 Jan 2018, 18:06 last edited by
        #2

        @JonB said in Designing a "composite widget":

        whether I'm going in the right direction.

        Yes, looks quite reasonable. Since you're also working with python you don't need to care about some peculiarities of C++, like if you were to design a widget that is to be put in a library, thus needing to keep the ABI binary compatible. Anyway, generally this is the correct approach.

        I see it that it must derive from generic QWidget, rather than, say, directly from QLineEdit?

        Unless your widget is going to modify some behaviour of QLineEdit I'd simply go with a QWidget subclass. Don't forget to expose the relevant/needed signals and/or slots from the child widgets though, at least if you want to allow the user programmer to have access to them, e.g. textChanged() and such.

        Read and abide by the Qt Code of Conduct

        J 1 Reply Last reply 9 Jan 2018, 19:12
        0
        • K kshegunov
          9 Jan 2018, 18:06

          @JonB said in Designing a "composite widget":

          whether I'm going in the right direction.

          Yes, looks quite reasonable. Since you're also working with python you don't need to care about some peculiarities of C++, like if you were to design a widget that is to be put in a library, thus needing to keep the ABI binary compatible. Anyway, generally this is the correct approach.

          I see it that it must derive from generic QWidget, rather than, say, directly from QLineEdit?

          Unless your widget is going to modify some behaviour of QLineEdit I'd simply go with a QWidget subclass. Don't forget to expose the relevant/needed signals and/or slots from the child widgets though, at least if you want to allow the user programmer to have access to them, e.g. textChanged() and such.

          J Offline
          J Offline
          JonB
          wrote on 9 Jan 2018, 19:12 last edited by JonB 1 Sept 2018, 19:13
          #3

          @kshegunov
          Thank you for confirming the approach is about right. That's what I'd do in C#/ASP.NET for a "UserControl". Qt ought to have that class :)

          I tend to be a bit lazy/ad hoc about exposing signals, attributes etc. from the embedded controls. I'm well aware it's "naughty", but I'll probably allow the embedded widgets to be visible to the outside world! (Well this is Python, so I think you'd have a hard time concealing them anyway....) Then I don't have to write all that behaviour/style transference code or guess what to expose/rewrite every time I find I want to access another property/function. Just insert a (date) "value" that's the overall date for the world to access.

          K 1 Reply Last reply 9 Jan 2018, 20:03
          0
          • J JonB
            9 Jan 2018, 19:12

            @kshegunov
            Thank you for confirming the approach is about right. That's what I'd do in C#/ASP.NET for a "UserControl". Qt ought to have that class :)

            I tend to be a bit lazy/ad hoc about exposing signals, attributes etc. from the embedded controls. I'm well aware it's "naughty", but I'll probably allow the embedded widgets to be visible to the outside world! (Well this is Python, so I think you'd have a hard time concealing them anyway....) Then I don't have to write all that behaviour/style transference code or guess what to expose/rewrite every time I find I want to access another property/function. Just insert a (date) "value" that's the overall date for the world to access.

            K Offline
            K Offline
            kshegunov
            Moderators
            wrote on 9 Jan 2018, 20:03 last edited by
            #4

            @JonB said in Designing a "composite widget":

            I tend to be a bit lazy/ad hoc about exposing signals, attributes etc. from the embedded controls. I'm well aware it's "naughty", but I'll probably allow the embedded widgets to be visible to the outside world!

            Well, it's just we C++ people tend to frown on breaking encapsulation, but it will work all the same.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • J Offline
              J Offline
              JonB
              wrote on 11 Jan 2018, 12:31 last edited by JonB 1 Nov 2018, 12:32
              #5

              This discussion about "composite widgets" in general has been useful.

              However, in my case of wanting to design "a line edit with a calendar popup", specifically, don't do this! I was fooled by the picture at http://doc.qt.io/qt-5/qdateedit.html#details showing it with a line-only interface. I have only just discovered that QDateEdit has http://doc.qt.io/qt-5/qdatetimeedit.html#calendarPopup-prop (would be nice if docs showed a pic using that!), which does exactly what I had in mind.

              1 Reply Last reply
              1

              1/5

              9 Jan 2018, 16:24

              • Login

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