Qt - 在不使用 WA_TranslucentBackground 的情况下以图像作为背景渲染 QFrame
Qt - render QFrame with image as background without using WA_TranslucentBackground
我需要设置 QFrame
背景图片:http://imgur.com/RnSghvV。这是我试过的:
setAutoFillBackground(true);
setWindowFlags(Qt::FramelessWindowHint);
setStyleSheet("background: transparent;");
QPalette p = this->palette();
p.setBrush(QPalette::Base, QPixmap("ipad.png"));
this->setPalette(p);
这就是我得到的:
如您所见,边缘有一个烦人的黑框,我想将其删除,然后只查看图像。我该怎么做?
P.S,可以使用 属性 Qt:: WA_TranslucentBackground
使其工作,如 所示。然而,在我的例子中,QFrame 将包含其他子部件,其中一些是通过 OpenGL 渲染的 QImages,设置 Qt:: WA_TranslucentBackground
使这些图像在 Windows 上不可见。所以我正在寻找一个不使用这个 属性.
的解决方案
编辑:
根据 Evgeny 提出的解决方案,我尝试了这个(我使用 325 x 400 作为小部件的尺寸,因为这些是图像的尺寸):
#include <QApplication>
#include <QLabel>
#include <QBitmap>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel l;
l.setWindowFlags(Qt::FramelessWindowHint);
QPixmap p(":/img/ipad.png");
l.setPixmap(p);
l.setScaledContents(true);
l.resize(300, 500); //just to test my idea
l.setMask(p.scaled(l.width(),l.height(),Qt::IgnoreAspectRatio,
Qt::SmoothTransformation).mask());
l.show();
return a.exec();
}
有了这个,它看起来像这样:
右侧和底部仍然显示灰色背景。如果我添加 setStyleSheet("background: transparent")
,灰色背景变为黑色。
main window 上的前景图像(在我们的例子中有透明度位)可以像这样应用:
#include "mainwindow.h"
#include <QLabel>
#include <QPixmap>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent, Qt::FramelessWindowHint)
{
setAttribute(Qt::WA_TranslucentBackground, true);
setStyleSheet("background-color: rgba(255, 255, 255, 255);"); // preventing child widgets from not being drawn
QLabel* pImageLabel = new QLabel;
QPixmap pixmap(":/RnSghvV.png");
pImageLabel->setPixmap(pixmap);
setCentralWidget(pImageLabel);
}
QLabel 是从 QFrame 派生出来的,所以它可以应用在同一个占位符中。请注意,拥有主程序 window 还需要应用 setAttribute(Qt::WA_TranslucentBackground, true)
、
好的,我终于得到了一个使用 setMask
的完整示例。主要问题是您的图像在边框处有额外的 space 。这是 OSX 的问题。在 windows 时,它可以很好地处理原始图像,但在 mac 时,我已经将其剪掉了。
你可以在这里得到它:
然后我可以在 mac 上使用 QFrame
获得工作示例。
在 .h
文件:
#include <QFrame>
#include <QPixmap>
class TestFrame : public QFrame
{
Q_OBJECT
public:
TestFrame(QWidget* p = 0);
protected:
void resizeEvent(QResizeEvent* e) override;
private:
QPixmap _pix;
};
在 .cpp
文件:
#include <QBitmap>
TestFrame::TestFrame(QWidget *p) :
QFrame(p, Qt::FramelessWindowHint | Qt::WindowSystemMenuHint),
_pix(":/img/i2.png")
{
QPalette pal = palette();
pal.setBrush(QPalette::Background, QBrush(_pix));
setPalette(pal);
resize(_pix.width(), _pix.height());
}
void TestFrame::resizeEvent(QResizeEvent *e)
{
QFrame::resizeEvent(e);
setMask(_pix.scaled(size()).mask());
}
这是 OS X
上的屏幕截图
第二种解决方案是使用 QLabel
而不是 QFrame
,如下所示:
#include <QApplication>
#include <QLabel>
#include <QBitmap>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel l;
l.setWindowFlags(Qt::FramelessWindowHint);
QPixmap p(":/img/ipad.png");
l.setPixmap(p);
l.setScaledContents(true);
l.resize(300, 500); //just to test my idea
l.setMask(p.scaled(l.width(),l.height(),Qt::IgnoreAspectRatio,
Qt::SmoothTransformation).mask());
l.show();
return a.exec();
}
我需要设置 QFrame
背景图片:http://imgur.com/RnSghvV。这是我试过的:
setAutoFillBackground(true);
setWindowFlags(Qt::FramelessWindowHint);
setStyleSheet("background: transparent;");
QPalette p = this->palette();
p.setBrush(QPalette::Base, QPixmap("ipad.png"));
this->setPalette(p);
这就是我得到的:
如您所见,边缘有一个烦人的黑框,我想将其删除,然后只查看图像。我该怎么做?
P.S,可以使用 属性 Qt:: WA_TranslucentBackground
使其工作,如 Qt:: WA_TranslucentBackground
使这些图像在 Windows 上不可见。所以我正在寻找一个不使用这个 属性.
编辑:
根据 Evgeny 提出的解决方案,我尝试了这个(我使用 325 x 400 作为小部件的尺寸,因为这些是图像的尺寸):
#include <QApplication>
#include <QLabel>
#include <QBitmap>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel l;
l.setWindowFlags(Qt::FramelessWindowHint);
QPixmap p(":/img/ipad.png");
l.setPixmap(p);
l.setScaledContents(true);
l.resize(300, 500); //just to test my idea
l.setMask(p.scaled(l.width(),l.height(),Qt::IgnoreAspectRatio,
Qt::SmoothTransformation).mask());
l.show();
return a.exec();
}
有了这个,它看起来像这样:
右侧和底部仍然显示灰色背景。如果我添加 setStyleSheet("background: transparent")
,灰色背景变为黑色。
main window 上的前景图像(在我们的例子中有透明度位)可以像这样应用:
#include "mainwindow.h"
#include <QLabel>
#include <QPixmap>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent, Qt::FramelessWindowHint)
{
setAttribute(Qt::WA_TranslucentBackground, true);
setStyleSheet("background-color: rgba(255, 255, 255, 255);"); // preventing child widgets from not being drawn
QLabel* pImageLabel = new QLabel;
QPixmap pixmap(":/RnSghvV.png");
pImageLabel->setPixmap(pixmap);
setCentralWidget(pImageLabel);
}
QLabel 是从 QFrame 派生出来的,所以它可以应用在同一个占位符中。请注意,拥有主程序 window 还需要应用 setAttribute(Qt::WA_TranslucentBackground, true)
、
好的,我终于得到了一个使用 setMask
的完整示例。主要问题是您的图像在边框处有额外的 space 。这是 OSX 的问题。在 windows 时,它可以很好地处理原始图像,但在 mac 时,我已经将其剪掉了。
你可以在这里得到它:
然后我可以在 mac 上使用 QFrame
获得工作示例。
在 .h
文件:
#include <QFrame>
#include <QPixmap>
class TestFrame : public QFrame
{
Q_OBJECT
public:
TestFrame(QWidget* p = 0);
protected:
void resizeEvent(QResizeEvent* e) override;
private:
QPixmap _pix;
};
在 .cpp
文件:
#include <QBitmap>
TestFrame::TestFrame(QWidget *p) :
QFrame(p, Qt::FramelessWindowHint | Qt::WindowSystemMenuHint),
_pix(":/img/i2.png")
{
QPalette pal = palette();
pal.setBrush(QPalette::Background, QBrush(_pix));
setPalette(pal);
resize(_pix.width(), _pix.height());
}
void TestFrame::resizeEvent(QResizeEvent *e)
{
QFrame::resizeEvent(e);
setMask(_pix.scaled(size()).mask());
}
这是 OS X
上的屏幕截图第二种解决方案是使用 QLabel
而不是 QFrame
,如下所示:
#include <QApplication>
#include <QLabel>
#include <QBitmap>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLabel l;
l.setWindowFlags(Qt::FramelessWindowHint);
QPixmap p(":/img/ipad.png");
l.setPixmap(p);
l.setScaledContents(true);
l.resize(300, 500); //just to test my idea
l.setMask(p.scaled(l.width(),l.height(),Qt::IgnoreAspectRatio,
Qt::SmoothTransformation).mask());
l.show();
return a.exec();
}