半透明QWidget应该是可点击的跨操作系统

时间:2011-08-04 17:32:00

标签: c++ qt cross-platform qwidget translucency

我正在尝试使用Qt(C ++)应用程序完成以下操作,跨操作系统。 在运行程序时,会弹出一个新窗口,一个全屏QWidget。现在我希望这是透明/透明的,因此用户实际上不会看到它。在这个“图层”上,用户可以拖动他/她的鼠标来绘制一个(红色)矩形,以选择一个区域 - 当鼠标被释放时 - 截取屏幕截图。

问题:
问题在于整个透明层事物,因为这似乎不能很好地跨OS。因为当我点击图层所在的位置时,要调用mousePressEvent(),我点击它到它下面的窗口就好像它不在那里。但是,在Ubuntu上,我没有。我希望在Windows上有同样的效果,但到目前为止我什么也没得到...... (显示另一个GUI对象,例如按钮,只会使按钮成为图层的可点击部分)

在Ubuntu 11.04 32位和Windows 7 Home Premium 64位上测试过。 (试图绕过Mac,这个问题会得到解决。)

那么有谁知道这会如何运作? 到目前为止我已经包含了我的代码。(清除了我的所有其他100次尝试。)

的main.cpp 在这里我设置了半透明背景,在这里我可能会错过一个设置或者没有正确配置的东西。

#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

另外,我认为我已经完成了谷歌在这个主题上发现的每一个结果,就像Qt的API文档一样。我已经认真地用尽了这个选项。 (我在Java中开始这个项目,但到目前为止,使用Qt的C ++似乎远没那么重要。)

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

这是一个完整而彻底的黑客攻击,但这是我所知道的唯一方法。截取屏幕截图,然后将其用作窗口小部件的背景,确保窗口中显示正确的部分,特别是调整大小或移动等。至少它是跨平台的。

然而,这也是在ARGB视觉效果和X11中不存在之前实现KDE 3虚假透明度的方式。