Yes, of course you can, but how easily it depends on how the widgets should be combined.
For example, if you want to create a button that has a label next to it, and not inside, you exit QWidget , add your QLabel and QPushButton members as members, and then just add them to the widget, the internal layout in the constructor. (I must point out that there are many different ways to do this).
However, for widgets that combine behavior in a new, visually distinct widget, you need to tell Qt how to draw it. So, subclass paintEvent(..) and draw the widget manually on QPainter(this) . And to match the widget with the current style, you need to get a QStyle to make a component drawing for you, which actually makes life easier.
Then you need to redefine mouse###Event(..) and manually handle the interaction with the mouse (and may also require interaction with the keyboard).
This is painstaking, but naturally less work, the closer your widget is to the existing one. In your case, I get from QToolButton as it already supports dropdown menus. Then override paintEvent(..) , call QStyle::drawControl(CE_PushButtonBevel, ... to draw the button, and then QStyle::drawControl(CE_CheckBox, ... to draw the checkbox in the correct state. Then override mousePressEvent(..) , work out if inside the scope of the checkbox, and change the corresponding state.
Ridiculous example
This pointless widget demonstrates some of the methods described above.
class WeirdCheckBoxButton : public QWidget { Q_OBJECT public: explicit WeirdCheckBoxButton( QWidget* parent = nullptr ) : QWidget( parent ), checked_( false ), down_( false ) {} virtual ~WeirdCheckBoxButton() {} bool isChecked() const { return checked_; } QSize sizeHint () const { return QSize( 128, 128 ); } public slots: virtual void setChecked( bool checked ) { if ( checked_ != checked ) { checked_ = checked; emit clicked( checked ); } } signals: void clicked( bool checked ); protected: virtual void paintEvent( QPaintEvent* event ) { Q_UNUSED( event ) QPainter p( this );
This is a subtle example, but it is ripe for copying and experimentation. For example, referring to butOpt.palette , you can adjust the colors of the displayed widgets depending on their state.