Stacks of transparent widgets and inputs passing through
Hello. I want to layer widgets in such a way that you can see through them and interact with all layers. The obvious thing seemed to be to subclass QStackedLayout and override the hiding behaviour. So I came up with this:
viewlayout.hpp:
Code:
Q_OBJECT
public:
public slots:
void setCurrentIndex (int);
private:
//! Shows everything in the widget.
void show_all ();
};
viewlayout.cpp:
Code:
}
int ViewLayout
:: addWidget (QWidget * w
) { show_all ();
return r;
}
int ViewLayout
:: insertWidget (int i,
QWidget * w
) { show_all ();
return r;
}
void ViewLayout :: setCurrentIndex (int) {
// Do nothing. There is no notion of "current" item.
}
void ViewLayout
:: setCurrentItem (QWidget *) { // Do nothing. There is no notion of "current" item.
}
void ViewLayout :: show_all () {
for (int i=0; i<count(); i++) {
itemAt(i)->widget()->raise();
itemAt(i)->widget()->show();
}
}
The widget that uses it:
view.hpp:
Code:
Q_OBJECT
public:
//! Remove the window from the view but do not destroy it.
//! \see QStackedLayout
//! \see QStackedLayout
// \see QStackedLayout
};
view.cpp:
Code:
ViewLayout * l = new ViewLayout ();
setLayout(l);
}
void View
:: removeWidget (QWidget * w
) { layout() -> removeWidget (w);
}
int View
:: addWidget (QWidget * w
) { ViewLayout * l = dynamic_cast<ViewLayout *>(layout());
return l -> addWidget (w);
}
int View
:: insertWidget (int i,
QWidget * w
) { ViewLayout * l = dynamic_cast<ViewLayout *>(layout());
return l -> insertWidget (i, w);
}
QWidget * View
:: widget (int i
) const { ViewLayout * l = dynamic_cast<ViewLayout *>(layout());
return l -> widget (i);
}
And here's a demo window to put into such a stack.
bouncetest.hpp:
Code:
class BounceTest
: public QFrame { Q_OBJECT
public:
private:
int vx;
int vy;
private slots:
void timeOut();
};
bouncetest.cpp:
Code:
#include <stdlib.h>
namespace {unsigned int count = 0;}
setFrameStyle
(QFrame::Panel|QFrame
::Plain);
setLineWidth(3);
QString s
= "%1 %1 %1 %1\n%1 %1 %1 %1\n%1 %1 %1 %1\n%1 %1 %1 %1\n";
obj->move(rand()%500,rand()%400);
vx = 11;
vy = 7;
QTimer::singleShot(200,
this,
SLOT(timeOut
()));
}
void BounceTest :: timeOut () {
int X = obj->x();
int Y = obj->y();
int W = width();
int H = height();
int Wo= obj->width();
int Ho= obj->height();
if ((X+Wo)>W || X<0)
vx = -vx;
if ((Y+Ho)>H || Y<0)
vy = -vy;
obj->move (X+vx,Y+vy);
QTimer::singleShot(150,
this,
SLOT(timeOut
()));
}
And finally, main.cpp:
Code:
View * bt = new View ();
bt->addWidget (new BounceTest());
bt->addWidget (new BounceTest());
bt->addWidget (new BounceTest());
bt->addWidget (new BounceTest());
bt->addWidget (new BounceTest());
bt->resize(800,600);
bt->show ();
At first glance, it seems okay except not all the Views have been resized.
Also, you can press the topmost button but none of the others. How do I rewrite BounceTest such that any click or mouse move not hitting any of its children wil propagate to the lower levels?
Thanks for reading this far.