1

Qt (C++) アプリ、クロス OS で次のことを達成しようとしています。プログラムを実行すると、フルスクリーンの QWidget という新しいウィンドウがポップアップします。これをシースルー/透明にしたいので、ユーザーは実際には見えません。この「レイヤー」で、ユーザーはマウスをドラッグして (赤い) 長方形を描画し、マウスを離したときにスクリーンショットが撮影される領域を選択できます。

問題:
これはクロス OS でうまく機能しないように見えるため、この問題は透過レイヤー全体に存在します。レイヤーがある場所をクリックすると、mousePressEvent() を呼び出すため、レイヤーが存在しないかのように、レイヤーをクリックしてその下のウィンドウに移動します。ただし、Ubuntuではそうしません。Windowsでも同じ効果が欲しいのですが、これまでのところ何もありません...
(ボタンなどの別のGUIオブジェクトを表示しても、ボタンはレイヤーのクリック可能な部分になるだけです)

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();
}

ウィジェット.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);
    }

ウィジェット.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 ドキュメントと同様に、Google がこの件に関して見つけるすべての結果を調べたと思います。私はこれのオプションを真剣に使い果たしました。(私は Java でこのプロジェクトを開始しましたが、Qt を使用した C++ は、これまでのところ、はるかに少ない作業のようです。)

どんな助けでも大歓迎です!

4

1 に答える 1

0

これは完全で完全なハックですが、私が知っている唯一の方法です。画面のスクリーンショットを撮り、それをウィジェットの背景として使用します。特にサイズ変更や移動などで、画面の右側がウィンドウに表示されることを確認します。少なくともクロスプラットフォームです。

ただし、ARGBビジュアルやX11には存在しなかったものなどの前に、KDE3の偽の透明度が実装された方法でもありました。

于 2011-08-05T03:48:15.257 に答える