PDA

View Full Version : Mouse events with StackAll QStackedLayout



Oleg
14th November 2011, 21:36
Hi, all.

In my video player I'm trying to have widget with controls on top of video widget. Using QStackedWidget or QStackedLayout with stackMode set to StackAll allowed me to place controls over video, but in this case i cannot handle mouse clicks in video widget. Here's simple test program to demonstrate my problem:



#include <QtGui>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget mainWidget;

mainWidget.setMinimumSize(300, 400);

QStackedLayout* stackedLayout = new QStackedLayout();
stackedLayout->setStackingMode(QStackedLayout::StackAll);

QWidget *videoWidget = new QWidget();
videoWidget->setLayout(new QVBoxLayout());
videoWidget->layout()->addWidget(new QPushButton("Video"));
static_cast<QVBoxLayout *>(videoWidget->layout())->insertStretch(-1);
stackedLayout->addWidget(videoWidget);

QWidget *controlWidget = new QWidget();
controlWidget->setLayout(new QVBoxLayout());
static_cast<QVBoxLayout *>(controlWidget->layout())->insertStretch(-1);
controlWidget->layout()->addWidget(new QPushButton("Controls"));
stackedLayout->addWidget(controlWidget);

mainWidget.setLayout(new QHBoxLayout());
static_cast<QHBoxLayout *>(mainWidget.layout())->addLayout(stackedLayout);
mainWidget.show();

return a.exec();
}


In this program it's impossible to click on "Video" button.

Any suggestions?

Thanks in advance.

grin
15th November 2011, 00:10
see answer of Thierry Bastian for https://bugreports.qt.nokia.com/browse/QTBUG-3868


Only the current page is active. The button on the other page just appears there because your current page is not opaque. That doesn't mean that it is transparent to mouse events.


So you can capture mouse events at mainWidget and send it to needed control (according with mouse position) - but this way assume that you have pointer to all needed control at all stack. The following code show example:


#include <QtGui>
class CMainWidget : public QWidget
{
QPushButton*m_video_but;
public:
CMainWidget(QWidget*parent=0):QWidget(parent)
{
setMouseTracking(true);
QStackedLayout*stack = new QStackedLayout(this);
stack->setStackingMode(QStackedLayout::StackAll);
QWidget*video_widget = new QWidget;
QVBoxLayout*v_layout = new QVBoxLayout(video_widget);
m_video_but = new QPushButton("Video");
v_layout->addWidget(m_video_but);
v_layout->addStretch();
stack->addWidget(video_widget);
QWidget*control_widget = new QWidget;
v_layout = new QVBoxLayout(control_widget);
v_layout->addStretch();
v_layout->addWidget(new QPushButton("Controls"));
stack->addWidget(control_widget);
stack->setCurrentWidget(m_control_widget);
}
private:
void mouseEvent(QMouseEvent*ev)
{
if(m_video_but->rect().contains(ev->pos()))
qApp->sendEvent(m_video_but,ev);
}
void mousePressEvent(QMouseEvent*ev) { mouseEvent(ev); }
void mouseReleaseEvent(QMouseEvent*ev) { mouseEvent(ev); }
void mouseDoubleClickEvent(QMouseEvent*ev) { mouseEvent(ev); }
};

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CMainWidget w;
w.show();
return a.exec();
}


The other way not use stack layout the following code illustrate it:


#include <QtGui>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QWidget mainWidget;
mainWidget.setFixedSize(150,80);

QHBoxLayout*h_layout = new QHBoxLayout(&mainWidget);
h_layout->setMargin(10);
h_layout->setSpacing(10);

QPushButton*but_left = new QPushButton("LEFT");
but_left->setFixedSize(60,60);
QPushButton*but_right = new QPushButton("RIGHT");
but_right->setFixedSize(but_left->size());
mainWidget.layout()->addWidget(but_left);
mainWidget.layout()->addWidget(but_right);

//NOTE: important that widget, which isn't in layout was a child of main widget
// also overlay shall be added to mainWidget child's list after it's layout
QPushButton*but_overlay = new QPushButton("overlay",&mainWidget);
but_overlay->setFixedSize(40,20);
QFont font;
font.setPixelSize(6);
but_overlay->setFont(font);
but_overlay->move(55,30); //at center of main widget;

mainWidget.show();
return a.exec();
}

Oleg
15th November 2011, 10:50
Thanks, grin.
The second way is exactly the same I was doing before trying QStackedLayout. I wanted to avoid manual positioning of overlay using layouts, but it seems to be inevitably...