2015-12-19 16 views
1

Мне нужно установить QFrame с фоновым изображением: http://imgur.com/RnSghvV. Это то, что я пробовал:Qt - визуализировать QFrame с изображением в качестве фона без использования WA_TranslucentBackground

setAutoFillBackground(true); 
setWindowFlags(Qt::FramelessWindowHint); 
setStyleSheet("background: transparent;"); 
QPalette p = this->palette(); 
p.setBrush(QPalette::Base, QPixmap("ipad.png")); 
this->setPalette(p); 

Это то, что я получаю:

enter image description here

Как вы можете видеть, есть досадная черная рамка по краям, которые я хочу, чтобы удалить, и просматривать только изображение. Как мне это сделать?

P.S, можно заставить его работать, используя свойство Qt:: WA_TranslucentBackground, как видно here. Однако в моем случае QFrame будет содержать другие подвижки, некоторые из которых являются QImages, отображаемыми через OpenGL, а установка Qt:: WA_TranslucentBackground делает эти изображения невидимыми для Windows. Поэтому я ищу решение, которое не использует это свойство.

Edit:

на основе решения, предложенного Евгений, я попробовал это (я использовал 325 по 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(); 
} 

С это, по-видимому, как это:

enter image description here

правая сторона и дно все еще показывает серый фон. Если я добавлю setStyleSheet("background: transparent"), серый фон станет черным.

+0

Возможно setStyleSheet («background-color: transparent;»); это исправит. – AlexanderVX

+0

'background' работает так же, как' background-color'. Я пробовал оба, не работает. – SexyBeast

+0

Может быть, 'setStyleSheet (" border-image: ipad.png ");' без касания палитры виджета будет работать? – dvvrd

ответ

3

Хорошо, я наконец получил полностью рабочий пример с использованием setMask. Основная проблема заключается в том, что ваше изображение имеет дополнительное пространство на границе. Это проблема для OSX. В окнах он отлично работает с оригинальным изображением, но для mac я его разрезал. Вы можете получить его здесь: http://smages.com/images/pic2016010ata.png

Тогда я мог бы получить рабочий пример на 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

enter image description here

Второе решение заключается в использовании 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(); 
} 
+0

Спасибо. Я проверю это. Можете ли вы предоставить скриншот вашего приложения в соответствии с этим кодом? – SexyBeast

+0

Он по-прежнему не работает должным образом. Пожалуйста, см. Мой отредактированный вопрос. – SexyBeast

+0

Я думаю, что проблема заключается в том, что размер и размер этикеток различаются. Поэтому я обновляю свой ответ с поддержкой масштабированного изображения. Вам не нужно масштабировать метку, но вы должны установить маску с масштабированной pixmap. Попробуй это. – Evgeny

1

Изображение переднего плана на главном окне (в нашем случае с прозрачностью битов) могут быть применены так:

#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, поэтому он может быть применен в том же заполнителем. Имейте в виду, что с основным окном программы вам также необходимо применить setAttribute(Qt::WA_TranslucentBackground, true),

+0

Umm, no. Я сказал, что виджет должен быть QFrame, поэтому не может установить pixmap, как это. – SexyBeast

+0

Вы также можете сделать углы рамки круглыми. – AlexanderVX

+0

Только что реализовано: QLabel - QFrame. Вы можете создать QLabel и присвоить его адрес QFrame *. – AlexanderVX