Designing a "composite widget"
-
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 aQCalendarWidget
. 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 theQPushButton
. 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 2QWidget
s, I see it that it must derive from genericQWidget
, rather than, say, directly fromQLineEdit
? - A
-
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. -
@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 aQWidget
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. -
@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.
-
@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.
-
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.