簡述
前些天從嵌入式Linux Qt4 切換到嵌入式Linux Qt5 開發平臺,發現遮罩不能用了,原本半透明的背景變成了黑色,全網找遍資料,沒有特別好的解決方案,無奈自己手擼擼一個,且測親測好用。
測試環境
- Qt5.6.2
- Linux 4.1
- Arm
方案一
透明背景只是顯示在父窗口上,不能遮住整個屏幕,不理想
QFrame *f = new QFrame(this);
f->setGeometry(100,100,100,1280);
f->setStyleSheet("QFrame{background-color: rgba(0,0,0, 177);}");
f->show();
方案二
這種在amr 上不生效,在pc 上沒問題,不過這個是整個QFrame 對象,包括子窗口統一透明處理
#ifndef __arm__
QFrame *f = new QFrame ();
f->setGeometry(200,100,100,1280);
QPalette p = f->palette();
p.setBrush(QPalette::Background, QColor(0,0,0));
f->setPalette(p);
f->setWindowOpacity(0.7f);
f->show();
#endif
方案三
這種和第一種差不多,但是透明背景是用的Dialog
並且 this
的第一個祖先必須是全屏的,否則遮罩(Dialog
)顯示區域就是遮罩父對象的區域
// arm pc 都有效
QDialog d(this->topLevelWidget()); //獲得這個窗口最頂層的父對象
//d.setGeometry(300,100,100,1280);
d.setWindowFlags(Qt::FramelessWindowHint); //在arm 上,如果不去掉標題欄,背景會變成黑色
d.setStyleSheet("QDialog{background-color: rgba(0,0,0,50%);}");
d.exec();
方案四
arm linux 有效,pc 未測試,不過應該大同小異,思路如下
- 截取全屏,用黑色半透明筆刷給圖片上色
- 根據遮罩的幾何位置,顯示對應圖片的位置
// ShadowFrame.h
#ifndef SHADOWFRAME_H
#define SHADOWFRAME_H
#include <QWidget>
class ShadowFrame : public QWidget
{
Q_OBJECT
explicit ShadowFrame(QWidget *parent = nullptr);
~ShadowFrame();
public:
static ShadowFrame *instance();
//設置遮罩位置和遮罩大小,並刷新遮罩
void updateShadow();
void updateShadow(int x, int y, int w, int h);
void updateShadow(const QRect &rect);
// QWidget interface
protected:
virtual void paintEvent(QPaintEvent *event);
QPixmap mPixmap;
};
#endif // SHADOWFRAME_H
// ShadowFrame.cpp
#include "ShadowFrame.h"
#include <QPainter>
#include "MyDebug.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QScreen>
ShadowFrame::ShadowFrame(QWidget *parent) :
QWidget(parent)
{
this->setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
this->mPixmap = QPixmap(qApp->desktop()->size());
this->mPixmap.fill(Qt::red);
}
ShadowFrame::~ShadowFrame()
{
}
ShadowFrame *ShadowFrame::instance()
{
static ShadowFrame w;
return &w;
}
void ShadowFrame::updateShadow()
{
QSize size = qApp->desktop()->size();
updateShadow(0, 0, size.width(), size.height());
}
void ShadowFrame::updateShadow(int x, int y, int w, int h)
{
updateShadow(QRect(x, y, w, h));
}
void ShadowFrame::updateShadow(const QRect &rect)
{
this->setGeometry(rect);
QScreen *screen = QApplication::primaryScreen();
QPixmap pixmap = screen->grabWindow(0); //截屏全屏
QPainter p(&mPixmap);
{
#if 01 // 由於我的應用程序在顯示時旋轉了270度,所以獲取到的圖片是橫向的,需要調整座標並旋轉。沒有這個需求的將編譯選項就改爲 0 可正常使用
p.save();
p.translate(pixmap.height(), 0);
p.rotate(90);
p.drawPixmap(0,0, pixmap);
p.restore();
#else
p.drawPixmap(0,0, pixmap);
#endif
}
p.fillRect(mPixmap.rect(), QColor(0, 0, 0, 150)); //黑色半透明筆刷
update();
}
void ShadowFrame::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.drawPixmap(QPoint(0, 0), mPixmap, geometry());
p.setBrush(Qt::blue);
}
#include "MainWindow.h"
#include <QApplication>
#include <QPushButton>
#include "ShadowFrame.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ShadowFrame::instance()->updateShadow();
ShadowFrame::instance()->show();
QWidget *w = new QWidget(/*ShadowFrame::instance()*/);
w->setAttribute(Qt::WA_DeleteOnClose);
//w->setStyleSheet("background-color: rgb(114, 159, 207);");
w->setGeometry(200, 300, 400, 400);
QPushButton *btn = new QPushButton(w);
btn->setGeometry(100, 100, 100, 100);
btn->setText("點我在");
connect(btn, &QPushButton::clicked, []{
qDebug("點擊成功");
});
w->show();
w->raise(); //將窗口置頂
return a.exec();
}