stefanadelbert
15th April 2010, 03:22
I have a QMenu that contains one QActionWidget. The QActionWidget contains a custom QWidget (CSpinBoxWidget), which comprises a QSpinBox and a custom QPushButton (CTitleButton).
When the CTitleButton is clicked I would like the QMenu to close.
I read here (http://lists.trolltech.com/qt-interest/2007-06/thread00463-0.html) that I will most likely need to do something with the handling of mouseReleaseEvent. I decided to use a QPushButton, but I did try with a QToolButton and couldn't get it working.
When the CTitleButton is clicked, CTitleButton::mouseReleaseEvent gets called. Then the event is passed to the parent of the CTitleButton, which is the CSpinBoxWidget.
Note: I tried connecting CSpinBoxWidget::titleClicked [signal] to QActionWidget::trigger [slot], but this didn't help.
class CTitleButton : public QPushButton
{
Q_OBJECT
public:
CTitleButton(QWidget* parent = 0) : QPushButton(parent) {}
void mouseReleaseEvent(QMouseEvent* event) {
QPushButton::mouseReleaseEvent(event);
QWidget::mouseReleaseEvent(event);
}
};
class CSpinBoxWidget : public QWidget
{
Q_OBJECT
public:
CSpinBoxWidget(const QString& t, QWidget* parent = 0) :
QWidget(parent)
{
value = new QSpinBox(parent);
value->setContextMenuPolicy(Qt::NoContextMenu);
title = new CTitleButton(parent);
title->setText(t);
QHBoxLayout* hLayout = new QHBoxLayout(parent);
hLayout->addWidget(title);
hLayout->addWidget(value);
hLayout->setSpacing(2);
hLayout->setMargin(2);
setLayout(hLayout);
// When the title button is clicked
connect(title, SIGNAL(clicked()),
this, SIGNAL(titleClicked()));
}
~CSpinBoxWidget() {}
public:
int Value() { return value->value(); }
void SetValue(int val) { value->setValue(val); }
void SetMinimum(int min) {
value->setMinimum(min);
}
void SetMaximum(int max) {
value->setMaximum(max);
}
signals:
void titleClicked();
private:
void mouseReleaseEvent(QMouseEvent* e) {
QWidget::mouseReleaseEvent(e);
}
private:
QSpinBox* value;
QPushButton* title;
};
But I don't understand how the event handling is supposed to work. When I create the QMenu, QWidgetAction and CSpinBox widget, does it matter who is whose parent as far as the event handling goes?
"QWidget::mouseReleaseEvent(event);" in CTitleButton::mouseReleaseEvent(QMouseEvent* event) ends up calling "event->ignore();", so does nothing really.
There is a documentation snippet in qwidgetaction.cpp that reads:
Note that it is up to the widget to activate the action, for example by reimplementing mouse event handlers and calling QAction::trigger().
But this doesn't make sense to me. How does the widget activate the action? Which mouseReleaseEvent functions need to be reimplemented? Who needs to call QAction::trigger (could only be derived QWidgetAction or QMenu)?
Any ideas?
Stefan
When the CTitleButton is clicked I would like the QMenu to close.
I read here (http://lists.trolltech.com/qt-interest/2007-06/thread00463-0.html) that I will most likely need to do something with the handling of mouseReleaseEvent. I decided to use a QPushButton, but I did try with a QToolButton and couldn't get it working.
When the CTitleButton is clicked, CTitleButton::mouseReleaseEvent gets called. Then the event is passed to the parent of the CTitleButton, which is the CSpinBoxWidget.
Note: I tried connecting CSpinBoxWidget::titleClicked [signal] to QActionWidget::trigger [slot], but this didn't help.
class CTitleButton : public QPushButton
{
Q_OBJECT
public:
CTitleButton(QWidget* parent = 0) : QPushButton(parent) {}
void mouseReleaseEvent(QMouseEvent* event) {
QPushButton::mouseReleaseEvent(event);
QWidget::mouseReleaseEvent(event);
}
};
class CSpinBoxWidget : public QWidget
{
Q_OBJECT
public:
CSpinBoxWidget(const QString& t, QWidget* parent = 0) :
QWidget(parent)
{
value = new QSpinBox(parent);
value->setContextMenuPolicy(Qt::NoContextMenu);
title = new CTitleButton(parent);
title->setText(t);
QHBoxLayout* hLayout = new QHBoxLayout(parent);
hLayout->addWidget(title);
hLayout->addWidget(value);
hLayout->setSpacing(2);
hLayout->setMargin(2);
setLayout(hLayout);
// When the title button is clicked
connect(title, SIGNAL(clicked()),
this, SIGNAL(titleClicked()));
}
~CSpinBoxWidget() {}
public:
int Value() { return value->value(); }
void SetValue(int val) { value->setValue(val); }
void SetMinimum(int min) {
value->setMinimum(min);
}
void SetMaximum(int max) {
value->setMaximum(max);
}
signals:
void titleClicked();
private:
void mouseReleaseEvent(QMouseEvent* e) {
QWidget::mouseReleaseEvent(e);
}
private:
QSpinBox* value;
QPushButton* title;
};
But I don't understand how the event handling is supposed to work. When I create the QMenu, QWidgetAction and CSpinBox widget, does it matter who is whose parent as far as the event handling goes?
"QWidget::mouseReleaseEvent(event);" in CTitleButton::mouseReleaseEvent(QMouseEvent* event) ends up calling "event->ignore();", so does nothing really.
There is a documentation snippet in qwidgetaction.cpp that reads:
Note that it is up to the widget to activate the action, for example by reimplementing mouse event handlers and calling QAction::trigger().
But this doesn't make sense to me. How does the widget activate the action? Which mouseReleaseEvent functions need to be reimplemented? Who needs to call QAction::trigger (could only be derived QWidgetAction or QMenu)?
Any ideas?
Stefan