2016-08-05 37 views
2

皆さん、私は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. 1つのペインタが必要です。もう1つはアクティブ化されていないので、あなたはそれを必要としません。

  2. repaint()が返す前に何らかの方法で絶対に絵を必要としない限り、repaint()に電話することは絶対にありません。イベントループを適切に実行し続けると、その必要はありません。

  3. update()paintEvent()から電話しないでください:ナンセンス(文字通り)です。

  4. ウィジェットを再描画する場合は、update()に電話してください:イベントループから更新をスケジュールします。未処理の複数の更新が統合され、イベントループが機能し、イベントの暴風が防止されます。

  5. コンパイラでを生成すると、さらにメモリ管理コードが生成されます。スマートポインタを使用して最初のステップを完了しました。これは良いことです。 2番目の操作を行います。CustomWidgetのインスタンスを値で保持します。明示的に動的に割り当てる必要はありません。 C++はCではないので、値を利用することができます。

  6. 単純なテストケースでは、3つのファイルは必要ありません。あなたのコードは、可能な限り数行に収まるように、main.cppのようにしてください。 Q_OBJECTマクロのためにファイルをmocする必要がある場合は、末尾に#include "main.moc"を追加し、プロジェクトにqmakeを再実行して通知してください。

このようなテストケースは、問題を修正した後に表示する必要があります。覚えておいてください:100kLOCプロジェクトではなく、テストケースです。あなたは3本のファイルに広がった貧弱な35行のコードを必要とせず、必要としません。さらに、コードを広げることによって、理解するのが難しくなります。

大きなプロジェクトでも、逆の場合に大幅なビルド時間の改善を示すことができない限り、ヘッダーファイルに完全にJavaスタイルの小さなクラスを実装できます。それはC++に属する唯一のJavaスタイルのものです。

// 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。 –

関連する問題