|
|
Creating a translucent QWidget Written on September 28, 2009, by Milot Shala. |
In my earlier post, I mentioned writing my personal video player so I wrote it and I’m working on it whenever I have time.
There are several cool video players out there with great user experience and one of them is VLC which has an awesome OSD (On Screen Display), for long I wanted this feature on my player.
This blog post is a step by step guide on how to create a rectangular semi-transparent widget that looks similar to VLC’s OSD.
Note: Result in the end is not exactly as seen in VLC screenshot above, but the widget can be adjusted more to look like it, and when a video is playing in full screen, the widget will look prettier as well.
Semi transparent widgets can be created using Qt’s backing store feature introduced in Qt 4.1. For more information on Transparent Backgrounds in Qt read this article.
For implementing a custom widget we start by inheriting QWidget class as shown in Listing 1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class CoolWidget : public QWidget { public: CoolWidget(QWidget *parent = 0); protected: void paintEvent(QPaintEvent *pnt); void mouseMoveEvent(QMouseEvent *evt); void mousePressEvent(QMouseEvent *evt); private: QPoint dragging_position; QColor current_color; QPushButton *cool_wdg_button[5]; }; |
Listing 1.
In CoolWidget class, mouseMoveEvent, mousePressEvent and paintEvent virtual members should be overridden in order to have implementation of specific features of this custom widget, below is the explanation of use for each virtual member:
mouseMoveEvent is used to move the widget.
mousePressEvent is used to get the QPoint where mouse position started dragging the widget.
paintEvent is used to paint the widget in our own way (to achieve our purpose of creating rectangular semi-transparent widget).
In paintEvent, QPainter and QPen classes are instantiated. QPainter and QPen classes are used for painting and drawing rectangular borders around the widget. After instantiating QPen, it’s width and styles are set. In CoolWidget’s case SolidLine pen style is used with RoundJoin as join style and SquareCap as cap style.
After adjusting QPen, alpha value of QColor class instantiated as current_color (See Listing 1) must be set to 100 via QColor::setAlpha method, then use QPainter class’ fillRect method by passing rect() and the current_color as parameters, then CoolWidget will get a semi-transparent background. In the constructor of CoolWidget’s current_color is set to Qt::black. See Listing 5.
We pass QPen to QPainter::setPen() and draw the rectangle using rect() method.
Implementation of paintEvent is shown in Listing 2.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | void CoolWidget::paintEvent(QPaintEvent *pnt) { QPainter painter(this); QPen pen; pen.setWidth(10); pen.setStyle(Qt::SolidLine); pen.setJoinStyle(Qt::RoundJoin); pen.setCapStyle(Qt::SquareCap); current_color.setAlpha(100); painter.fillRect(rect(), current_color); painter.setPen(pen); painter.drawRect(rect()); } |
Listing 2.
mousePressEvent is about giving dragging_position a value, which is the subtraction of global position with top left corner of widget’s frame geometry as shown in Listing 3.
1 2 3 4 5 6 7 8 | void CoolWidget::mousePressEvent(QMouseEvent *evt) { if(evt->button() == Qt::LeftButton) { dragging_position = evt->globalPos() - frameGeometry().topLeft(); evt->accept(); } } |
Listing 3.
mouseMoveEvent is about moving the widget. Widget movement is done using move() method, by passing global position QPoint subtracted by dragging_position QPoint as shown in Listing 4.
1 2 3 4 5 6 7 8 | void CoolWidget::mouseMoveEvent(QMouseEvent *evt) { if(evt->buttons() == Qt::LeftButton) { move(evt->globalPos() - dragging_position); evt->accept(); } } |
Listing 4.
In constructor the widget is resized to 300×300, current_color is set to black and 5 QPushButtons are created as shown in Listing 5.
1 2 3 4 5 6 7 8 9 10 11 12 13 | CoolWidget::CoolWidget(QWidget *parent) : QWidget(parent) { current_color = Qt::black; resize(300, 300); for(int i = 0; i < 5; i++){ cool_wdg_button[i] = new QPushButton(QString("Cool Button %1").arg(i), this); cool_wdg_button[i]->move(10, i * 40); } } |
Widget is used with the following snippet:
1 | CoolWidget *coolwdg = new CoolWidget(this); |
And CoolWidget in action:
If you find this post useful or have questions regarding the topic, don’t hesitate to either to leave a comment or write me an email at: milot.shala [at] gmail [dot] com
-
Swetha
-
http://spartansoft.org Milot Shala
-
http://mms-core.weebly.com/ MamdouhAlShamy
-
http://mms-core.weebly.com/ MamdouhAlShamy
4,426 views

