Поиск:

Закрытая темаСоздание новой темы Создание опроса
> [QT] QPainter, QPixmap, paintEvent 
V
    Опции темы
Moby
Дата 14.1.2009, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 6.10.2008

Репутация: нет
Всего: нет



Возник вопрос о создании Pixmap'a с заданым размером.

Вот когда мне надо было создать Pixmap и загрузить картинку на него я делал так - в *.h писал QPixmap img а в *.cpp я писал img.load(.....).

Вопрос - как мне создать пиксмап заданного размера?

В *.h я написал QPixmap img1, в *.cpp стал писать img1(600,600,-1, ?.....?)  

Не могу понять какой четвертый параметр должен быть. Пишу QPixmap ::NoOptim выдает ошибку. Может не то пишу?

'NoOptim' : is not a member of 'QPixmap'    
 'NoOptim' : undeclared identifier    

И второй вопрос почему при вызове img.Resize(41,43) ругается

'resize' : is not a member of 'QPixmap'
PM MAIL ICQ   Вверх
mes
Дата 14.1.2009, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 7
Всего: 250



Цитата(Moby @  14.1.2009,  14:46 Найти цитируемый пост)
Возник вопрос о создании Pixmap'a с заданым размером.

не мешало бы для начала с этим ознакомится : http://doc.trolltech.com/4.4/qpixmap.html



--------------------
PM MAIL WWW   Вверх
SABROG
Дата 14.1.2009, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Цитата(Moby @  14.1.2009,  15:46 Найти цитируемый пост)
Вопрос - как мне создать пиксмап заданного размера?


Код

QPixmap pix(100, 100);


Если потом воспользуешься загрузкой картинки, то размер сбросится на размер картинки. Нужно, чтобы рисовать собственную картинку.

Если надо картинке задать размер, то:

Код

QPixmap pix("file.png");
pix.scaled(QSize(100, 100));




--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Moby
Дата 19.1.2009, 16:10 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 6.10.2008

Репутация: нет
Всего: нет



Это наверно мой последний вопрос будет по этой тематике. :)

Я уже спрашивал, как мне реализовать зависимость скорости от времени. 

Предложенный вариант я как-то не разобрал. Хотя наверно стоит. Но тут уже суть в другом возникла, вроде придумал что-то, а работает не так как надо.

Вот есть два варианта как я изменил функцию paintEvent
Код

void Class::paintEvent(QPaintEvent *event)
{    
    
    QTimer *timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()), this, SLOT(moving()));
    
    
    QPainter painter(this);
    painter.drawPixmap(x+m-img.height()/2,y+m-img.height()/2,img1);
    
    timer->start(1000);
    update();
}

void Class::moving()
{
    m++;
}


В этом случае просто получается вот что - первую секунду объект не движится, потом начинает двигаться и каждую секунду всё быстрее, почему????? И вообще почему объект двигается? Ведь m меняется только после ого как таймер 1-у секунду отработает или этот update() в paintEvent обновляет все, а не только paintEvent? 

Потом я решил синхронизировать update() с таймером. 

Код

void Class::paintEvent(QPaintEvent *event)
{    
    
    QTimer *timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()), this, SLOT(moving()));
    
        QTimer *timer1 = new QTimer(this);
    connect(timer1,SIGNAL(timeout()), this, SLOT(update()));
    
    QPainter painter(this);
    painter.drawPixmap(x+m-img.height()/2,y+m-img.height()/2,img1);
    
    timer->start(1000);
        timer1->start(1000);
    
}

void Class::moving()
{
    m++;
}


И тут как раз получилось, то что я ожидал в первом случае. Т.е. проходит секунда и объект перемещается и остается на новом месте, проходит еще секунда и он на вдвое большее расстояние перемещается.


PM MAIL ICQ   Вверх
SABROG
Дата 19.1.2009, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Расскажи, что ты хочешь сделать.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
pan2004
Дата 19.1.2009, 16:30 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 357
Регистрация: 28.7.2007

Репутация: 6
Всего: 9



Цитата(Moby @  19.1.2009,  16:10 Найти цитируемый пост)
и каждую секунду всё быстрее, почему

Потому что ты в бесконечном цикле создаешь все новые и новые таймеры, которые просто давят своим количеством, дергая сигнал намного чаще, чем ты ожидаешь(вообще создавать таким образом таймеры, ла еще и в paintEvent- та еще ЖЕСТЬ).
А во втором случае: зачем создавать два таймера, когда можно обойтись одним? К одному сигналу можно кучу слотов нацепить...

Добавлено через 2 минуты и 21 секунду
и вообще есть функция QObject::startTimer(), которая подойдет имхо в твоем случае намного лучше

Добавлено через 3 минуты и 47 секунд
не говоря о том что память с каждым новым таймером будет утекать...


--------------------
Qt4/C++ fan
WinXP SP3: MSVC++2005 Qt4.5.1 Boost1.39
сыграем в дурака?
PM MAIL   Вверх
Moby
Дата 19.1.2009, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 6.10.2008

Репутация: нет
Всего: нет



pan2004, спасибо, сейчас попробую создавать таймер не в paintEvent. 

SABROG, наверно и правду стоило было сперва объяснить нормально, что я хотел сделать.

Код

void Class::paintEvent(QPaintEvent *event)
{    
    QPainter painter(this);
    painter.drawPixmap(x+m-img.height()/2,y+m-img.height()/2,img1);
    
    m++;
    //m+=2; 

    update();
}


Ну вот, тут просто рисуется пиксмап и двигается. Как часто обновляется paintEvent не знаю, но допустим 0.5 сек. И получается, что у меня каждые 0.5 сек объект перемешается на 1-н пиксель.

Мне надо сделать регулировку скорости. Я сперва просто тупа сделал так, что можно было вручную ставить на сколько m будет изменяться. С одной стороны вот оно решение. Но тогда если объект перемещается больше чем на 2-а пикселя появляется эффект дёрганья.

Как мне это нормально реализовать. 

Что мне на предудушей страничке советовали пока не могу приспособить к моей проге. Не очень понял тот пример, ну где 
Код

void Widget::animate()
{
    elapsed = (elapsed + qobject_cast<QTimer*>(sender())->interval()) % 1000;
    repaint();
}


Посоветуйте плиз. 

Это сообщение отредактировал(а) Moby - 19.1.2009, 16:48
PM MAIL ICQ   Вверх
pan2004
Дата 19.1.2009, 16:54 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 357
Регистрация: 28.7.2007

Репутация: 6
Всего: 9



Цитата(Moby @  19.1.2009,  16:47 Найти цитируемый пост)
Как часто обновляется paintEvent не знаю, но допустим 0.5 сек. И получается, что у меня каждые 0.5 сек объект перемешается на 1-н пиксель.

Нельзя расчитывать, что ивенты будут вызываться постоянное колво раз в секунду. Здесь update() в паинт ивенте приводит к бесконечному циклу.
И вообще хватит изобретать велосипеды. Есть Graphics View и есть QTimeLine. посмотри этот класс.


--------------------
Qt4/C++ fan
WinXP SP3: MSVC++2005 Qt4.5.1 Boost1.39
сыграем в дурака?
PM MAIL   Вверх
SABROG
Дата 19.1.2009, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Это кусок выдранный с 2D Painting Example. Там создается таймер на 50 мс. Это 20 фреймов в секунду (1000/50).
В elapsed вычисляется время прошедшее c последней перерисовки. Затем это значение используется, чтобы корректировать радиус круга. По модулю 1000 все значения будут в пределах 0-1000. Например если прошло 1002 мс, то elapsed будет 2. По логике 1000 мс - полный цикл + 2 мс, а это значит, что для рисовальщика фиолетово прошел полный цикл и 2мс или всего 2мс, т.к. картинка будет одной и той же. 

В общем часть с elapsed можешь опустить. Ориентируйся на таймер в 50 мс (20 фреймов в секунду, почти как видео) и метод repaint(), который будет незамедлительно вызывать твой переопределенный paintEvent, в котором ты и будешь что-то рисовать.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Moby
Дата 19.1.2009, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 6.10.2008

Репутация: нет
Всего: нет



pan2004, спасибо за наводку, буду смотреть.

SABROG, пробую! 

И так, вот результаты. 

Из пары Graphics View и QTimeLine я использовал только QTimeLine вот с таким вод кодом.

Код

QTimeLine *timeLine = new QTimeLine(20000, this);
timeLine->setFrameRange(0, 600);    
connect(timeLine, SIGNAL(frameChanged(int)), this, SLOT(moving(int )));

void Class::moving()
{
    m++;
}


В setFrameRange(0, 600); я грубо говоря выставляю расстаяние на которое должен двигаться объект. А конструкторе я выставляю duration-продолжительность, за которое он должен пройти это расстаяние.

Я понимаю что в setFrameRange(0, 600); выставляется кол-во кадров, но это я думаю можно и так использовать. В итоге получается то что надо, но.... Объект начинает двигаться с замедлением, ну как бы пол секунды идет разгон, и то же самое в конце получается. Постепеная остановка. Не знаю, может я что то не то делаю, но вот так вот.

Дальше я вчитался в то что написал SABROG и сделал так.

Код

QTimer *timer = new QTimer(this);
connect(timer,SIGNAL(timeout()), this, SLOT(repaint()));
timer->start(50);

void For_Frogs::paintEvent(QPaintEvent *event)
{    
    QPainter painter(this);
    painter.begin(this);
    painter.drawPixmap(x+m-img.height()/2,y+m-img.height()/2,img);
    painter.end();
    m++;
}


Все работает так как надо. В этой связке я правильно понимаю, что каждые 50 мс происходит движение объекта на 1-н пиксель?
PM MAIL ICQ   Вверх
pan2004
Дата 19.1.2009, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 357
Регистрация: 28.7.2007

Репутация: 6
Всего: 9



Цитата(Moby @  19.1.2009,  20:21 Найти цитируемый пост)
Объект начинает двигаться с замедлением, ну как бы пол секунды идет разгон, и то же самое в конце получается. Постепеная остановка.

Почитай ассистент. Там сказано, что по умолчанию параметр QTimeLine::сurveShape установлен в EaseInOutCurve(как раз такое поведение).
Соответственно, его можно и изменить(например сделать линейным)


--------------------
Qt4/C++ fan
WinXP SP3: MSVC++2005 Qt4.5.1 Boost1.39
сыграем в дурака?
PM MAIL   Вверх
Moby
Дата 19.1.2009, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 117
Регистрация: 6.10.2008

Репутация: нет
Всего: нет



pan2004, спасибо!

P.S. А вот такой вопрос. 

Почему у меня не запускается прога не через Студию? В папке Debug есть ехе'шник, жму на него а говорит "Приложению не удалось запуститься, поскольку QtCore4d.dll не был найден."

Как с этим бороться, мне надо будет завтра\после завтра эту чудесную бета-альфа-прогу запускать на другом ПК.

Я вот сделал так.

Мой компутер -> свойства -> вкладка Дополнительно - > кнопка Переменные среды -> раздел Системные переменные -> переменная Path -> изменить и всталяеш туда пути "C:\QT\4.4.3\;C:\QT\4.4.3\bin\;"

А без это никак не обойтись? Неужели QT должно стоять и на том ПК, на котором собиаются запускать программу?

Это сообщение отредактировал(а) Moby - 19.1.2009, 22:07
PM MAIL ICQ   Вверх
JackYF
Дата 19.1.2009, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 7
Всего: 162



Moby, Модератор: Пожалуйста, один топик - один вопрос.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Закрытая темаСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0777 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.