The real issue with making the QRubberband
semi-transparent is that mplayer
is painting on a window without Qt having any knowledge of it. Hence Qt itself cannot act as a compositor to generate the required effect.
One possibility would be to make the QRubberBand
a top level window. That way the compositing is the responsibility of the underlying graphics system rather than Qt.
With that in mind try the following. Firstly a utility base class to manage the geometry...
class abstract_rubber_band {
public:
virtual QRect get_geometry () const
{
return(QRect(m_parent->mapFromGlobal(widget().geometry().topLeft()), widget().size()));
}
virtual void set_geometry (const QRect &rect)
{
widget().setGeometry(map_rect(rect));
}
protected:
explicit abstract_rubber_band (QWidget *parent)
: m_parent(parent)
{}
/*
* @param point Coords relative to effective parent.
*/
QPoint map_point (QPoint point) const
{
if (point.x() < 0)
point.rx() = 0;
else if (point.x() >= m_parent->width())
point.rx() = m_parent->width() - 1;
if (point.y() < 0)
point.ry() = 0;
else if (point.y() >= m_parent->height())
point.ry() = m_parent->height() - 1;
point = m_parent->mapToGlobal(point);
return(point);
}
QRect map_rect (QRect rect) const
{
return(QRect(map_point(rect.topLeft()), map_point(rect.bottomRight())));
}
private:
QWidget &widget ()
{
return(dynamic_cast<QWidget &>(*this));
}
const QWidget &widget () const
{
return(dynamic_cast<const QWidget &>(*this));
}
QWidget *m_parent;
};
Now use the above as a base of the required rubber band class...
class rubber_band: public abstract_rubber_band,
public QRubberBand {
using super = QRubberBand;
public:
/*
* @param parent Note that this isn't actually used as the
* parent widget but rather the widget to which
* this rubber_band should be confined.
*/
explicit rubber_band (QWidget *parent)
: abstract_rubber_band(parent)
, super(QRubberBand::Rectangle)
{
setAttribute(Qt::WA_TranslucentBackground, true);
}
protected:
virtual void paintEvent (QPaintEvent *event) override
{
QPainter painter(this);
painter.fillRect(rect(), QColor::fromRgbF(0.5, 0.5, 1.0, 0.25));
QPen pen(Qt::green);
pen.setWidth(5);
painter.setPen(pen);
painter.setBrush(Qt::NoBrush);
painter.drawRect(rect().adjusted(0, 0, -1, -1));
/*
* Display the current geometry in the top left corner.
*/
QRect geom(get_geometry());
painter.drawText(rect().adjusted(5, 5, 0, 0),
Qt::AlignLeft | Qt::AlignTop,
QString("%1x%2+%3+%4").arg(geom.width()).arg(geom.height()).arg(geom.left()).arg(geom.top()));
}
};
The above rubber_band
class should almost be a drop in replacement for QRubberBand
. The main difference is that rather than reading/writing its geometry with geometry
/setGeometry
you must use get_geometry
/set_geometry
-- those will perform the mapping to/from global coordinates.
In your particular case create the rubber_band with...
rubberBand = new rubber_band(ui->videoShowLabel);