2016-08-05 7 views
2

Hy all, я новичок в QT и C++, и я хотел посмотреть, как использовать QPainter и события в Qt, но я застрял из-за сообщение об ошибке во время выполнения, мой исходный код:«QPainter :: drawRects: Painter not active» ошибка C++/QT

main.cpp

#include "customwidget.h" 
#include <QApplication> 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    QScopedPointer<QWidget> widget(new customWidget()); 
    widget->resize(240, 120); 
    widget->show(); 

    return a.exec(); 
} 

и заголовок:

#ifndef CUSTOMWIDGET_H 
#define CUSTOMWIDGET_H 

#include <QWidget> 
#include <QMouseEvent> 
#include <QPoint> 
#include <QPainter> 

class customWidget : public QWidget 
{ 
    Q_OBJECT 
public: 
    explicit customWidget(QWidget *parent = 0); 
    void paintEvent(QPaintEvent *); 
    void mouseMoveEvent(QMouseEvent *event); 
    void mousePressEvent(QMouseEvent *event); 

private: 
    QPoint m_mousePos; 
    QRect m_r2; 
signals: 

    void needToRepaint(); 
public slots: 
}; 

#endif // CUSTOMWIDGET_H 

и .cpp:

#include "customwidget.h" 

customWidget::customWidget(QWidget *parent) : QWidget(parent) 
{ 
    QRect m_r2; 
    QPoint m_mousePos; 

    QObject::connect(this, SIGNAL(needToRepaint()), this, SLOT(repaint())); 
} 

void customWidget::paintEvent(QPaintEvent *) 
{ 
    QPainter painter(this); 

// ############ First Rectangle **************************************** 

    QRect r1 = rect().adjusted(10, 10, -10, -10); 
    painter.setPen(QColor("#FFFFFF")); 
    painter.drawRect(r1); 

// ############ Seconde Rectangle **************************************** 

    QRect r2(QPoint(0, 0), QSize(100, 100)); 


    m_r2.moveCenter(m_mousePos); 

    QPainter painter2; 
    QPen pen; 
    painter2.setPen(QColor("#000000")); 
    pen.setWidth(3); 
    painter2.setPen(pen); 
    painter2.drawRect(m_r2); 
    update(); 



} 

void customWidget::mouseMoveEvent(QMouseEvent *event) 
{ 

    m_mousePos = event->pos(); 

    emit needToRepaint(); 
} 

Я попытался найти его в Интернете и увидел, что это потому, что QPainter не находится в paintEvent, но это не так в моем коде, спасибо за вашу помощь.

+0

Вам необходимо называть 'painter2.begin (objectWhereToDraw)' и 'painter2.end()'. Или просто создайте его как 'QPainter painter2 (objectWhereToDraw)'. – ilotXXI

ответ

1
  1. Вам нужен только один художник. Второй не был активирован, и вам это все равно не нужно.

  2. Никогда не звоните repaint(), если вам не нужна картина, которая должна быть сделана до того, как будет возвращена repaint() (это то, что происходит!). Если вы поддерживаете цикл событий правильно, вам это никогда не понадобится.

  3. Не называть update() от paintEvent(): это абсурд (буквально).

  4. Если вы хотите перерисовать виджет, вызовите update(): он планирует обновление из цикла событий. Несколько выдающихся обновлений объединены, чтобы поддерживать цикл событий и предотвращать бури событий.

  5. Пусть компилятор сгенерирует еще больше код управления памятью для вас. Вы сделали первый шаг, используя интеллектуальные указатели - это хорошо. Теперь сделайте второй: удерживайте экземпляр CustomWidget по значению. Он не должен быть явно динамически распределен. C++ - это не C, вы можете использовать значения.

  6. В простом случае вам не нужны три файла. Ваш код должен соответствовать как можно меньше строк, в одном main.cpp. Если вам нужно moc-файл из-за Q_OBJECT макросов, добавьте #include "main.moc" в конец и повторно запустите qmake в проекте, чтобы обратить внимание на него.

Вот как выглядит такой тестовый пример после устранения проблем. Помните: это тестовый пример, а не проект 100kLOC. Вы не нуждаетесь и не хотите, чтобы скудные 35 строк кода распространялись на три файла. Более того, распространяя код, который вы усложняете для себя, понимаете.

Даже в больших проектах, если вы не можете показать значительные улучшения времени сборки, если вы делаете наоборот, вы можете иметь множество небольших классов, реализованных в Java-стиле полностью в файлах заголовков. Речь идет о единственном Java-стиле - все, что принадлежит C++.

// https://github.com/KubaO/stackoverflown/tree/master/questions/simple-paint-38796140 
#include <QtWidgets> 

class CustomWidget : public QWidget 
{ 
    QPoint m_mousePos; 
public: 
    explicit CustomWidget(QWidget *parent = nullptr) : QWidget{parent} {} 
    void paintEvent(QPaintEvent *) override; 
    void mouseMoveEvent(QMouseEvent *event) override { 
     m_mousePos = event->pos(); 
     update(); 
    } 
}; 

void CustomWidget::paintEvent(QPaintEvent *) 
{ 
    QPainter painter(this); 

    auto r1 = rect().adjusted(10, 10, -10, -10); 
    painter.setPen(Qt::white); 
    painter.drawRect(r1); 

    auto r2 = QRect{QPoint(0, 0), QSize(100, 100)}; 
    r2.moveCenter(m_mousePos); 
    painter.setPen(QPen{Qt::black, 3, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin}); 
    painter.drawRect(r2); 
} 

int main(int argc, char ** argv) { 
    QApplication app{argc, argv}; 
    CustomWidget w; 
    w.show(); 
    return app.exec(); 
} 
+0

Большое спасибо за ваш ответ и советы. Я попробую сразу: D. –