Russian Qt Forum
Октябрь 01, 2024, 22:33 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Начало работы с 2d графикой в Qt  (Прочитано 13448 раз)
couatl
Гость
« : Апрель 05, 2009, 22:03 »

Смотрел темы, все вопросы уровнем больший чей мой, поэтому пишу тему.
Задача нарисовать  что-то на Frame при возникновении к.-л. события (нажатие кнопки, запуск программы и т.д.)
Как я это понимаю: сигнал нажатия кнопки связать с функцией, в которой я буду вызывать функции рисования.
Но проблема даже не чтоб связать эти вещи. Я пока стою на шагу ранее.

Все что я находил в книгах:
"Чтобы начать рисовать на устройстве рисования (обычно это виджет), мы просто создаем объект QPainter и передаем ему указатель на устройство. Например:
void MyWidget::paintExent(QPaintEvent *event)
{
 QPainter painter(this)
 ...
}"

Но куда это вставлять и как использовать не понял. Все исходники, что я нашел, огромны и онять что там что для меня пока невозможно.

Так вот заготовка куда я хочу вставить рисование:
main.cpp
Код:
#include <QApplication>
#include "draw.h"

int main(int argc, char *argv[])
{
  QApplication app(argc, argv);
  mainDialog *dialog = new mainDialog;
  dialog->show();
  return app.exec();
}

draw.h
Код:
#ifndef DRAW_H 
#define DRAW_H

#include <QDialog>
#include <QPainter>

class QFrame;

class mainDialog : public QDialog
{
  Q_OBJECT
  public:
    mainDialog(QWidget *parent = 0);
//  signals:
//  private slots:
  private:
//////// Frame ////////
    QFrame *paintFrame;
//////// Painter ////////
    QPainter framePainter;
};
#endif

draw.cpp
Код:
#include <QtGui> 

#include "draw.h"

mainDialog::mainDialog(QWidget *parent) : QDialog(parent)

    paintFrame = new QFrame;
    paintFrame->setFixedHeight(500);
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(paintFrame);
    setLayout(mainLayout);
}

Буду рад советам, хорошим ссылкам на примеры.
Записан
spirit
Гость
« Ответ #1 : Апрель 05, 2009, 22:29 »

поставь точку останова в деструктор mainDialog и посмотри вызывается ли он после закрытия проги.  Подмигивающий
Записан
couatl
Гость
« Ответ #2 : Апрель 05, 2009, 22:44 »

Вопросы:
как?
зачем?
и какое отношение имеет к рисованию на рамке?
Записан
spirit
Гость
« Ответ #3 : Апрель 05, 2009, 23:00 »

память не освобожнается.
либоже в стеке создавай окно либоже уничтожай его явно.
Записан
couatl
Гость
« Ответ #4 : Апрель 05, 2009, 23:30 »

Бланшет в начале своей книге пишет, что потеря памяти в малых приложениях мала и в начале не указал. Я не далеко зашел в изучении его книги - не успел.

Как я понял надо так:
Код
C++ (Qt)
#include <QApplication>
#include "draw.h"
 
int main(int argc, char *argv[])
{
 QApplication app(argc, argv);
 mainDialog *dialog = new mainDialog;
 dialog->show();
 return app.exec();
 delete dialog;
}

так?


Ну а если по теме? Очень важна Ваша помощь в начинании.
« Последнее редактирование: Апрель 06, 2009, 10:06 от pastor » Записан
spirit
Гость
« Ответ #5 : Апрель 05, 2009, 23:41 »

объект опять таки не удалится из-за этого
Код
C++ (Qt)
 return app.exec();//вываливается из main
 delete dialog;//никогда сюда не попадем.
 
есть три варианта
1. создавать объект в стеке
Код
C++ (Qt)
int main(int argc, char *argv[])
{
 QApplication app(argc, argv);
 mainDialog dialog;
 dialog.show();
 return app.exec();
}
 
2. удалять явно
Код
C++ (Qt)
int main(int argc, char *argv[])
{
 QApplication app(argc, argv);
 mainDialog *dialog = new mainDialog;
 dialog->show();
 bool res = app.exec();
 delete dialog;
 return res;
}
 
3. использую Qt::WA_DeleteOnClose
Код
C++ (Qt)
int main(int argc, char *argv[])
{
 QApplication app(argc, argv);
 mainDialog *dialog = new mainDialog;
 dialog->setAttribute(Qt::WA_DeleteOnClose);
 dialog->show();
 return app.exec();
}
 
по теме, почитай про QPainter про QPixmap (т.к. на нем тоже можно рисовать) ну и более навороченная штука это The Graphics View Framework описалово есть в доках.
edited: ах да, забыл сказать, чтобы еще глянуть QWidget::paintEvent (тут-то собственно и нужно рисовать на виджете).
« Последнее редактирование: Апрель 05, 2009, 23:43 от spirit » Записан
couatl
Гость
« Ответ #6 : Апрель 06, 2009, 06:33 »

Спасибо, иначе бы долго делал эту ошибку(не удаление окна), так как среди знакомых никто не разбирается в Qt.

По теме:
Читал, из того что понял -  делал следующие действия:
сначала сделал так:
draw.cpp
Код:
#include <QtGui> 

#include "draw.h"

mainDialog::mainDialog(QWidget *parent) : QDialog(parent)

    paintFrame = new QFrame;
    paintFrame->setFixedHeight(500);
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(paintFrame);
    setLayout(mainLayout);
}

void paintFrame::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setPen(Qt::blue);
    painter.setFont(QFont("Arial", 30));
    painter.drawText(rect(), Qt::AlignCenter, "Qt");
}

он он ругался, что paintFrame не декларирован.
Потом подумал, может надо создать класс QMyFrame, который бы наследовал QFrame, и там прописать paintEvent, но счел эту идею ещё глупее, чем прошлую, которую реализировал и написал выше.

По поводу QPixmap - я так понял эта некая аналогия Bitmap'а в VS и Delphi. на нем можно рисовать, а потом выгрузить все нарисованное на особый виджет.
« Последнее редактирование: Апрель 06, 2009, 06:36 от couatl » Записан
spirit
Гость
« Ответ #7 : Апрель 06, 2009, 08:14 »

Спасибо, иначе бы долго делал эту ошибку(не удаление окна), так как среди знакомых никто не разбирается в Qt.
ну тут в основном С++, специфический кьютишный метод -- это с использованием флага Qt::WA_DeleteOnClose  Улыбающийся

он он ругался, что paintFrame не декларирован.
Потом подумал, может надо создать класс QMyFrame, который бы наследовал QFrame, и там прописать paintEvent, но счел эту идею ещё глупее, чем прошлую, которую реализировал и написал выше.
все правильно ты думал, ничего глупого. Улыбающийся
другой же вариант (без наследования) это установить ивент фильтр на фрейм и отлавливать его QPaintEvent
в твоем диалоге, т.е. будет это выглядить следующим образом
Код
C++ (Qt)
#include "draw.h"
 
mainDialog::mainDialog(QWidget *parent) : QDialog(parent)
{  
   paintFrame = new QFrame;
   paintFrame->installEventFilter(this);//устанавливаем фильтр событий
   paintFrame->setFixedHeight(500);
   QVBoxLayout *mainLayout = new QVBoxLayout;
   mainLayout->addWidget(paintFrame);
   setLayout(mainLayout);
}
 
bool mainDialog::eventFilter(QObject *o, QEvent *e)
{
   if (o == painFrame && e->type() == QEvent::Paint) {
       //русуем здесь
   }
   return QDialog::eventFilter(o, e);
}
 

По поводу QPixmap - я так понял эта некая аналогия Bitmap'а в VS и Delphi. на нем можно рисовать, а потом выгрузить все нарисованное на особый виджет.
ну не помню как там в делфи, но да, на пиксмапе рисуешь и отображаешь при помощи QLabel.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #8 : Апрель 06, 2009, 10:09 »

ну не помню как там в делфи, но да, на пиксмапе рисуешь и отображаешь при помощи QLabel.

...на пиксмапе рисуешь и отрисовываешь на виджете при помощи QPainter::drawPixmap(...)
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #9 : Апрель 06, 2009, 10:10 »

он он ругался, что paintFrame не декларирован.

Добавь #include <QFrame> в таой draw.cpp


А это что?

Цитировать
void paintFrame::paintEvent(QPaintEvent *)

нужно:

Цитировать
void mainDialog::paintEvent(QPaintEvent *)

и в нем рисуем
« Последнее редактирование: Апрель 06, 2009, 10:17 от pastor » Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
spirit
Гость
« Ответ #10 : Апрель 06, 2009, 10:19 »

он на фрейме хочет рисовать, а не на диалоге.
Записан
spirit
Гость
« Ответ #11 : Апрель 06, 2009, 10:20 »

ну не помню как там в делфи, но да, на пиксмапе рисуешь и отображаешь при помощи QLabel.

...на пиксмапе рисуешь и отрисовываешь на виджете при помощи QPainter::drawPixmap(...)
в случае с QLabel наследовать ничего не нужно.  Подмигивающий
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #12 : Апрель 06, 2009, 10:32 »

Вот простейший пример:

Код
C++ (Qt)
#include <QApplication>
#include "draw.h"
 
int main(int argc, char *argv[])
{
 QApplication app(argc, argv);
 mainDialog dialog;
 dialog.show();
 return app.exec();
}

Код
C++ (Qt)
#ifndef DRAW_H
#define DRAW_H
 
#include <QWidget>
 
class mainDialog : public QWidget
{
 Q_OBJECT
public:
   mainDialog(QWidget *parent = 0);
 
protected:
   virtual void paintEvent(QPaintEvent *);
};
 
#endif

Код
C++ (Qt)
#include "draw.h"
 
#include <QPainter>
 
mainDialog::mainDialog(QWidget *parent)
   : QWidget(parent)
{
}
 
void mainDialog::paintEvent(QPaintEvent *)
{
   QPainter painter(this);
   painter.setPen(Qt::blue);
   painter.setFont(QFont("Arial", 30));
   painter.fillRect(rect(), Qt::red);
   painter.drawText(rect(), Qt::AlignCenter, tr("Hello Qt!"));
}

Советую почитать про QPainter в ассистанте
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.28 секунд. Запросов: 23.