Полупрозрачный QWidget должен быть интерактивным - PullRequest
1 голос
/ 04 августа 2011

Я пытаюсь сделать следующее с приложением Qt (C ++), кросс-ОС.После запуска программы появляется новое окно, полноэкранный QWidget.Теперь я хочу, чтобы это было прозрачным, чтобы пользователь на самом деле не видел его.На этом «слое» пользователь может перетащить свою мышь, чтобы нарисовать (красный) прямоугольник, чтобы выбрать область, на которой - когда мышь отпущена - сделан снимок экрана.

Проблема:
Проблема заключается во всем, что связано с прозрачным слоем, поскольку это не очень хорошо работает в ОС.Потому что, когда я нажимаю на то, где находится слой, чтобы вызвать mousePressEvent (), я щелкаю по нему в окне под ним, как будто его там даже нет .На Ubuntu, однако, я не.Я хочу такой же эффект в Windows, но до сих пор ничего не получил ...
(При появлении другого объекта с графическим интерфейсом, например кнопки, кнопка станет лишь частью щелкающего слоя)

Протестированона Ubuntu 11.04 32-битной и Windows 7 Home Premium 64-битной.(Попытка обойтись с Mac, будет ли решена эта проблема.)

Так кто-нибудь знает, как это будет работать? Я уже включил свой код. (Очистка всех моих 100 других попыток.) ​​

main.cpp Здесь я установил translucentBackground, здесь я, вероятно, скучаюпараметр или что-то не настроено правильно.

#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

Кроме того, я думаю, что я просмотрел все результаты, которые Google найдет по этому вопросу, так же, как и документы API Qt.У меня серьезно закончились варианты для этого.(Я начал этот проект на Java, но C ++ с Qt, по-видимому, пока гораздо меньше работает.)

Любая помощь будет очень признательна!

1 Ответ

0 голосов
/ 05 августа 2011

Это полный и полный взлом, но это единственный известный мне способ сделать это.Сделайте снимок экрана с экрана, а затем используйте его в качестве фона для вашего виджета, убедившись, что правая часть экрана отображается в окне, особенно при изменении размеров или перемещениях и т. Д. По крайней мере, это кроссплатформенность.

Тем не менее, это был способ, которым поддельная прозрачность KDE 3 была реализована до таких вещей, как визуальные эффекты ARGB и того, чего не было в X11.

...