前些天从嵌入式Linux Qt4 切换到嵌入式Linux Qt5 开发平台,发现遮罩不能用了,原本半透明的背景变成了黑色,全网找遍资料,没有特别好的解决方案,无奈自己手撸撸一个,且测亲测好用。
透明背景只是显示在父窗口上,不能遮住整个屏幕,不理想
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
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
#include "MyDebug.h"
#include
#include
#include
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
#include
#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();
}