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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QPainter для совсем новичков  (Прочитано 21577 раз)
niktagor
Гость
« : Май 15, 2010, 15:46 »

 Здравствуйте. Заранее большое спасибо всем, кто откликнется. Пытаюсь разобраться, как рисовать на виджетах с помощью QPainter. После прочтения документации, мой мозг сгенерировал вот такой код:
Код:
#include <QtGui>
#include <QPainter>
int main(int argc, char **argv) {

    QApplication app(argc,argv);
    QWidget wgt;
    wgt.resize(500,500);

    QPainter painter;
    painter.begin(&wgt);
    painter.setPen(QPen(Qt::black,3));
    painter.drawLine(QPointF(5,5),QPointF(100,100));
    painter.end();

    wgt.show();

    return app.exec();
}

Окошко запускается, а линия не рисуется. В чем причина?
Вот такая штука на отладке:

Запускается D:\programs\2\debug\2.exe...
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::setPen: Painter not active
QPainter::end: Painter not active, aborted
D:\programs\2\debug\2.exe завершился с кодом 0

Из пока не получилось вырвать работающий кусок кода. Нашел вот тут такое сообщение:
Цитировать
Вот тебе минималистический пример виджета, на котором можно что-нибудь рисовать:
Код
Код:
class PaintWidget : public QWidget
{
    Q_OBJECT

    public:
        PaintWidget(QWidget *parent = 0);
        void draw( QPainter  *painter);
    protected:
        void paintEvent(QPaintEvent *event);
};
PaintWidget::PaintWidget(QWidget *parent)
    : QWidget(parent)
{
    setPalette(QPalette(QColor(250, 250, 200)));
    setAutoFillBackground(true);
}

void PaintWidget::paintEvent(QPaintEvent * /* event */)
{
     QPainter  painter(this);
    draw(&painter);
}

void PaintWidget::draw( QPainter  *painter)
{
    painter->setRenderHint( QPainter ::Antialiasing, true);
    painter->drawLine(0, 0, 20, 30);
}

Но у меня не получается его вставить в свой проект. Сборщик аж 4 раза ругается вот так:
undefined reference to `vtable for PaintWidget'
на строчке
Код:
: QWidget(parent)


Если кто-нибудь напишет минималистичный код, в котором все работает и выводит на экран какие-нибудь точки или линии, буду очень благодарен. Или подскажите, как мне с этим всем добром разобраться.
Записан
alexman
Гость
« Ответ #1 : Май 15, 2010, 16:14 »

http://doc.qt.nokia.com/4.6/painting-basicdrawing.html
Записан
jack_r
Гость
« Ответ #2 : Май 15, 2010, 16:54 »

Но у меня не получается его вставить в свой проект. Сборщик аж 4 раза ругается вот так:
undefined reference to `vtable for PaintWidget'
Пример этого кода нужно поместить в отдельный класс с заголовком и исходником paintwidget.h и paintwidget.cpp, а затем включить заголовок в main.cpp.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #3 : Май 15, 2010, 20:10 »

>>Окошко запускается, а линия не рисуется. В чем причина?
В документации сказано, что рисовать на виджете, можно только из его обработчика события рисования, т.е.
MyWidget::paintEvent(...)
Иные способы рисования на виджете не для новичка
Записан

Юра.
niktagor
Гость
« Ответ #4 : Май 15, 2010, 22:59 »

Но у меня не получается его вставить в свой проект. Сборщик аж 4 раза ругается вот так:
undefined reference to `vtable for PaintWidget'
Пример этого кода нужно поместить в отдельный класс с заголовком и исходником paintwidget.h и paintwidget.cpp, а затем включить заголовок в main.cpp.


А можете объяснить, что из этого текста куда записать, и что нужно в main написать, чтобы он нарисовал мне что-нибудь?
Записан
alexman
Гость
« Ответ #5 : Май 16, 2010, 10:08 »

Написали же, что нужно void QWidget::paintEvent ( QPaintEvent * event ) переопределять.
Записан
marbius
Гость
« Ответ #6 : Май 16, 2010, 10:52 »

Вот Вам, в принципе, минимум, чтобы начать самостоятельно рисовать.

Код:
#include <QtGui>

class myWidget : public QWidget
{
    public:
        myWidget (QWidget *parent=0) : QWidget(parent)
        {
        }

        void paintEvent(QPaintEvent *pe)
        {    QPainter p(this);
             // тут и только тут должны быть все Ваши "рисования"
             p.drawLine(0,0,100,100);
        }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    myWidget w;
    w.show();
    return a.exec();
}

« Последнее редактирование: Май 16, 2010, 10:56 от µarbius » Записан
niktagor
Гость
« Ответ #7 : Май 16, 2010, 12:51 »

 Большое спасибо! Работает. Позже я разберусь, что все это значит, а пока на более простых вещах потренируюсь. Нигде я не смог такого хорошего примера найти.
Записан
niktagor
Гость
« Ответ #8 : Май 16, 2010, 16:10 »

 А если я хочу, например, чтобы на виджете рисовалось не при его создании, а при нажатии кнопочки, что нужно сделать? Нужно paintEvent поключить к сигналу кнопки в качестве слота, а внутри него уже проверять, был ли это сигнал кнопки или другое неподходящее событие? Или попроще можно?
Записан
jack_r
Гость
« Ответ #9 : Май 16, 2010, 16:12 »

Но у меня не получается его вставить в свой проект. Сборщик аж 4 раза ругается вот так:
undefined reference to `vtable for PaintWidget'
Пример этого кода нужно поместить в отдельный класс с заголовком и исходником paintwidget.h и paintwidget.cpp, а затем включить заголовок в main.cpp.


А можете объяснить, что из этого текста куда записать, и что нужно в main написать, чтобы он нарисовал мне что-нибудь?

paintwidget.h - заголовочный файл
Код:
#include <QWidget>

class PaintWidget : public QWidget
{
    Q_OBJECT

    public:
        PaintWidget(QWidget *parent = 0);
        void draw( QPainter  *painter);
    protected:
        void paintEvent(QPaintEvent *event);
};

paintwidget.cpp - исходный код
Код:
#include <QPainter>

#include "paintwidget.h"

PaintWidget::PaintWidget(QWidget *parent)
    : QWidget(parent)
{
    setPalette(QPalette(QColor(250, 250, 200)));
    setAutoFillBackground(true);
}

void PaintWidget::paintEvent(QPaintEvent * /* event */)
{
     QPainter  painter(this);
    draw(&painter);
}

void PaintWidget::draw( QPainter  *painter)
{
    painter->setRenderHint( QPainter ::Antialiasing, true);
    painter->drawLine(0, 0, 20, 30);
}

main.cpp - исходный код
Код:
#include <QtGui>

#include "paintwidget.h"

int main(int argc, char **argv) {

    QApplication app(argc,argv);
    PaintWidget wgt;
    wgt.resize(500,500);
    wgt.show();

    return app.exec();
}
Записан
jack_r
Гость
« Ответ #10 : Май 16, 2010, 16:22 »

А если я хочу, например, чтобы на виджете рисовалось не при его создании, а при нажатии кнопочки, что нужно сделать? Нужно paintEvent поключить к сигналу кнопки в качестве слота, а внутри него уже проверять, был ли это сигнал кнопки или другое неподходящее событие? Или попроще можно?
Да, примерно так.
Если более подробно, то в paintEvent() в зависимости от состояния флага рисовать что-либо. А флаг изменять в слоте вызываемом при клике на кнопку.
Код:
void MyWidget::paintEvent(QPaintEvent *e)
{
  Q_UNUSED(e);

  QPainter  painter(this);
  if (mPaintRect)
  {
    // рисуем прямоугольник
    painter.drawRect(0, 0, 10, 10);
  }
}

void MyWidget::doPaintRect() // слот
{
  mPaintRect = !mPaintRect;
  update(); // вызывает paintEvent
}

Ещё нужно инициализировать флаг в конструкторе.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #11 : Май 16, 2010, 19:05 »

>>ужно paintEvent поключить к сигналу кнопки в качестве слота
paintEvent - не слот, следовательно, как слот использовать нельзя
Записан

Юра.
niktagor
Гость
« Ответ #12 : Май 18, 2010, 10:42 »

Большое спасибо всем, кто ответил!! Потихоньку начинаю понимать, что к чему.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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