Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: daenux от Октябрь 27, 2010, 20:48



Название: QWidget и фон!
Отправлено: daenux от Октябрь 27, 2010, 20:48
Здравствуйте господа форумчане!

Создаю небольшое проект в Qt, основной класс графического интерфейса наследуеться от QWidget, вопросы:

1. Стоит ли наследоваться от QWidget, может лучше например от QFrame на будующее так сказать...
2. Какого типа изоброжение подходит для того что бы выресовывать ее на QWidget (допустим) - как фон? (например, одно из условий: что бы не тормозил проект при изменении размеров этого окна - во многих программах есть фоновые рисунки, и они не тормозят при изменении размеров этих программ, например: Opera 10, Qt Creator...)
3. И если QWidget подходит (исходя из первого вопроса), тогда как на него установить фоновую картинку?

Хотелось бы конечно использовать QWidget...
Пробую установить фоновую картинку таким образом:

Код:
void IFaceWClass::paintEvent(QPaintEvent *event)
 {
    painter = new QPainter(this);
    background = new QPixmap("D:\\ear.png");
    painter->drawPixmap(0, 0, background->width(), background->height(), *background);
 }

Но невыходит, в документации сказанно что с QPainter нужно работать в обработчике события paintEvent, класса-потомка QWidget - вроде все делаю правильно - картинка есть, painter, background - объявленны в заголовочном файле этого класса (т.е. IFaceWClass)...

Разьясните мне пожалуйста выше описанные моменты, я изучал документацию, рылся по форуму, но так и не получилось отрисовать фоновую картинку на QWidget...


Название: Re: QWidget и фон!
Отправлено: alexman от Октябрь 27, 2010, 21:08
А кто будет удалять память? Если при каждой перерисовке грузить данные с жесткого диска, то может томозить!


Название: Re: QWidget и фон!
Отправлено: GreatSnake от Октябрь 27, 2010, 21:14
см. QPalette.


Название: Re: QWidget и фон!
Отправлено: pethead от Октябрь 28, 2010, 03:46
а что надо создавать каждый раз qpainter?
посм в примерах qt, вроде что то было там с фоном (mice).


Название: Re: QWidget и фон!
Отправлено: daenux от Октябрь 28, 2010, 06:15
Хорошо, буду создовать в конструкторе класса объекты...

На счет QPolette:

Код:
palette = new QPalette();
    palette->setBrush(this->backgroundRole(), QBrush(QPixmap("D:\\ear.png")));
    this->setPalette(*palette);

(это в конструкторе класса)

И все тот же нулевой результат...


Название: Re: QWidget и фон!
Отправлено: GreatSnake от Октябрь 28, 2010, 09:04
palette->setBrush(QPalette::Window, QBrush(QPixmap("D:\\ear.png")));
Создавать QPalette через new не нужно. QWidget сам сохранит всё что нужно.


Название: Re: QWidget и фон!
Отправлено: daenux от Октябрь 28, 2010, 09:15
Да! Так получилось (QPalette) - Спасибо!!!

Вот только как сделать так что бы это самое изоброжение расстягивалось либо сжималось отностительно размеров QWidget?

А то изображение достаточно большого размера и картинка выходит за границы виджета...

И где здесь людям Спасибо кнопочку нажимать?


Название: Re: QWidget и фон!
Отправлено: daenux от Октябрь 28, 2010, 09:18
В документации по QPalette я такого что то найти не могу...


Название: Re: QWidget и фон!
Отправлено: GreatSnake от Октябрь 28, 2010, 10:17
Вот один из вариантов:
Код
C++ (Qt)
#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QPaintEvent>
 
class MyWidget : public QWidget
{
public:
MyWidget( const QString& fn, QWidget* p = 0 )
: QWidget( p )
{
bg.load( fn );
}
 
protected:
void paintEvent( QPaintEvent* e )
{
if( bg.isNull() )
{
QWidget::paintEvent( e );
return;
}
 
QPainter p( this );
 
qreal xs = qreal( width() ) / qreal( bg.width() );
qreal ys = qreal( height() ) / qreal( bg.height() );
 
if( xs != 1 || ys != 1 )
{
QImage img;
int cx = qRound( e->rect().x() / xs );
int cy = qRound( e->rect().y() / ys );
int cw = qRound( e->rect().width() / xs );
int ch = qRound( e->rect().height() / ys );
cw = qMin( cw, bg.width() - cx );
ch = qMin( ch, bg.height() - cy );
img = bg.copy( cx, cy, cw, ch );
cw = qRound( cw * xs );
ch = qRound( ch * ys );
img = img.scaled( cw, ch, Qt::IgnoreAspectRatio,
/*Qt::SmoothTransformation :*/ Qt::FastTransformation );
p.drawImage( e->rect().topLeft(), img );
} else
{
p.drawImage(
e->rect().topLeft(),
bg,
QRect( e->rect().x(), e->rect().y(),
qMin( e->rect().width(), bg.width() ),
qMin( e->rect().height(), bg.height() ) ) );
}
}
QImage bg;
};
 
int main( int argc, char* argv[] )
{
QApplication a( argc, argv );
 
MyWidget w( argc > 1 ? argv[1] : "" );
w.show();
 
return a.exec();
}
 
Его большой плюс в том, что он самый быстрый и не нужно держать на Xserver-e или GDI пиксмап

Второй вариант проще в написании, но намного тормознутее:
Код
C++ (Qt)
#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QPaintEvent>
 
class MyWidget : public QWidget
{
public:
   MyWidget( const QString& fn, QWidget* p = 0 )
   : QWidget( p )
   {
       bg.load( fn );
       br.setTextureImage( bg );
   }
 
protected:
   void paintEvent( QPaintEvent* e )
   {
       QPainter p( this );
 
       br.setMatrix( QMatrix(
               qreal( width() ) / qreal( bg.width() ), 0, 0,
               qreal( height() ) / qreal( bg.height() ), 0, 0 ) );
       p.setPen( Qt::NoPen );
       p.setBrush( br );
       p.drawRect( e->rect() );
   }
   QImage bg;
   QBrush br;
};
 
int main( int argc, char* argv[] )
{
   QApplication a( argc, argv );
 
   MyWidget w( argc > 1 ? argv[1] : "" );
   w.show();
 
   return a.exec();
}
 


Название: Re: QWidget и фон!
Отправлено: daenux от Октябрь 28, 2010, 11:25
Уху!!! Спасибо!!! Код суперский!!!

Работает все замечательно!!!

Документацию изучил, все понял - Qt::IgnoreAspectRatio!!!

Только вот работает с форматом .jpg а с .png нет, почему?


Название: Re: QWidget и фон!
Отправлено: daenux от Октябрь 28, 2010, 11:27
Тот код, что первый я имею в веду...

Сейчас второй вариант испробую!!!


Название: Re: QWidget и фон!
Отправлено: daenux от Октябрь 28, 2010, 11:38
Отличия в производительности что то не заметил...

Оба метода работают превосходно!!!


Название: Re: QWidget и фон!
Отправлено: GreatSnake от Октябрь 28, 2010, 11:40
Цитировать
Отличия в производительности что то не заметил...
Зависит от размера окна и самой подложки.


Название: Re: QWidget и фон!
Отправлено: daenux от Октябрь 28, 2010, 11:44
Кстате, PNG отображает так же прекрасно, но только ту что мне нужна, не отображает...

Почему это может быть? (картинка warty из релиза 10.10 Ubuntu)


Название: Re: QWidget и фон!
Отправлено: GreatSnake от Октябрь 28, 2010, 11:59
Натравите на этот файл 'file' - вполне возможно, что это и не png вовсе.
Если при загрузке картинки не указывать её формат, то Qt пытается определить формат по расширению и в таком случае может обломиться.


Название: Re: QWidget и фон!
Отправлено: daenux от Октябрь 28, 2010, 12:30
Ахахахаха!!! Спасибо большое вам!!! Это JPEG (JFIF standart 1.02)!!! Он ее отрисовал замечательно просто!!!


Название: Re: QWidget и фон!
Отправлено: CuteBunny от Октябрь 29, 2010, 16:25
Че-то все так сложнооо :o

А если qss??? Если опыт есть в css... :D

Код:
QPushButton#searchMenuButton{
text-align: center;
padding-left: 10px;
background-position:center;
background-image: url(:/images/param_search_normal.png); /*этот путь в файле ресурсов*/
background-repeat: no-repeat;
border: none;
min-width: 155px;
max-width: 155px;
min-height: 57px;
max-height:155px;
}


Название: Re: QWidget и фон!
Отправлено: GreatSnake от Октябрь 29, 2010, 17:29
Цитировать
Че-то все так сложнооо
И что там сложного?

Цитировать
А если qss??? Если опыт есть в css..
Ну ка пример CSS описания позволяющего по размеру виджета скейлить подложку?

"background-image:" может создавать только QPixmap. Иногда не всех это устраивает.