PDA

View Full Version : Translucent QWidget should be clickable cross-os



Newanz
7th August 2011, 13:43
Hi there, first time poster here. Got a bit of a difficult issue with Qt cross OS. I'm trying to accomplish the following with a Qt (C++) app, cross OS:
Upon running the program a new window pops up, a fullscreen QWidget. Now I want this to be see-through/transparent, so the user won't actually see it. On this 'layer' a user can drag his/her mouse to draw a (red) rectangle to select an area which is - when the mouse is released - taken a screenshot of.

The problem:
The issue lays in the whole transparent layer thing since this doesn't appear to work well cross OS. Because when I click on where the layer is, to invoke the mousePressEvent(), I click through it on to the window below it as if it isn't even there. On Ubuntu, however, I do not. I want the same effect on Windows, but thus far I got nothing...
(Making another GUI object appear, such as button, would only make the button a clickable part of the layer)

Tested on Ubuntu 11.04 32-bit and Windows 7 Home Premium 64-bit. (Trying to get around to a Mac one, would this issue be solved.)

So does anyone know how this would work?
I've included my code thus far. (Clearing out all my 100 other attempts.)

main.cpp
Here I set the translucentBackground, here I probably miss a setting or something is not configured right.

#include <QtGui/QApplication>
#include "widget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
//Fullscreen app
w.showFullScreen();
w.setAttribute(Qt::WA_NoSystemBackground);
w.setAttribute(Qt::WA_TranslucentBackground);
w.setMouseTracking(true);
w.setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
//Show
w.show();
return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "QDebug"
Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget)
{
this->setWindowFlags(Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
QPalette palette(Widget::palette());
palette.setColor(backgroundRole(), Qt::white);
setPalette(palette);
this->clicked = false;
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::mousePressEvent ( QMouseEvent * event )
{
//Record start
if (event->button() == Qt::LeftButton){
x = event->globalX();
y = event->globalY();
this->clicked = true;
width = 0;
height = 0;
}
}
void Widget::mouseMoveEvent ( QMouseEvent * event )
{
if (this->clicked == true){
int x2 = event->globalX();
int y2 = event->globalY();
if(x < x2){
width = x2 - x;
}else{
width = x - x2;
//Resetting startpoint when dragging to the left side on your screen, copy from java so this doesn't actually works yet.
x = x - width-2;
}
if(y < y2){
height = y2 - y;
}else{
height = y - y2;
//Resetting startpoint when dragging to the left side on your screen, copy from java so this doesn't actually works yet.
y = y - height-2;
}
//Redraw rectangle
update();
qDebug("wa");
}
}
void Widget::mouseReleaseEvent ( QMouseEvent * event )
{
if (event->button() == Qt::LeftButton)
{
//Record end
qDebug("-------");
this->clicked = false;
}
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setPen(Qt::red);
painter.drawRect(x,y,width,height);
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtGui>
#include<QMouseEvent>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
bool clicked;
int x,y,width,height;
void mousePressEvent ( QMouseEvent * event );
void mouseMoveEvent ( QMouseEvent * event );
void mouseReleaseEvent ( QMouseEvent * event );
protected:
void paintEvent(QPaintEvent *);
};
#endif // WIDGET_H

Also, I think I've gone through every result Google will find on this subject, same as the API docs of Qt. I've seriously run out of options for this one. (I started this project in Java, but C++ with Qt seems to be, thus far, far less work.)

Any help would very much be appreciated!

xx77abs
2nd September 2011, 19:58
I don't know if you've already solved this, but you could paint your whole window with
QColor backgroundColor = QColor::fromRgb(0,0,0,1);

that way, it would seem that there is no window, and you would receive mouse events ;)