9

長方形を描くにはどうすればよいですか?

私は2つの異なる方法を試しました。

void MyWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::black);
    QRect rect = QRect(290, 20, 70, 40);
    painter.drawText(rect, Qt::AlignCenter,
                      "Data");
    painter.drawRect(rect);
}

これは正常に機能しますが(パラメーターに名前が付けられておらず、使用されていなくても)、QPaintEventを使用したくありません*使用できません。

そこで、関数の名前を変更してみました。

void MyWidget::draw()
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::black);
    QRect rect = QRect(290, 20, 70, 40);
    painter.drawText(rect, Qt::AlignCenter,
                      "Data");
    painter.drawRect(rect);
}

これは何も表示しません(まだエラーはありません)。

QPaintEvent *を使用しないと、なぜ機能しないのですか??

4

5 に答える 5

10

ペイントイベントは、ウィジェットを再描画する必要があるときにペイントシステムによって呼び出されるメソッドです。そのため、独自のメソッドに名前を付けるだけでは機能しません。ペイントシステムによって呼び出されることはありません。

あなたは本当にを使用する必要がありますQPaintEvent。それはあなたに描かれる必要があるrectを与えます。この四角形はウィジェットのサイズに基づいているため、ペイントイベントで明示的な四角形を使用する代わりに、ウィジェットを適切なサイズに設定します。ウィジェットが移動したり、サイズが変更されたりすると、ペイントイベントが生成されます。

void MyWidget::paintEvent(QPaintEvent *event)
{
    QRect rect = event->rect();
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::black);
    painter.drawText(rect, Qt::AlignCenter,
                      "Data");
    painter.drawRect(rect);
}

ペイントロジックを別のメソッドに分離したい場合は、それで問題ありません。ただし、ペイントイベントから呼び出す必要があります。

void MyWidget::paintEvent(QPaintEvent *event)
{
    QRect rect = event->rect();
    draw(rect);
}

void MyWidget::draw(QRect &rect)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::black);
    painter.drawText(rect, Qt::AlignCenter,
                      "Data");
    painter.drawRect(rect);
}

あなたが言ったようにペイントイベントを完全にバイパスし、表示する静的な長方形だけを作成したい場合、1つの方法はそれをピックスマップに一度描画してQLabelに表示することです:

QPixMap pix(200,100);
QPainter painter(&pix);
// do paint operations
painter.end()
someLabel.setPixmap(pix)
于 2012-12-31T20:00:32.237 に答える
2

必要なデータpaintEvent()は、それを含むクラスのフィールド、この場合はのプライベートフィールドとしてアクセスできる必要がありますMyWidget。これらのプライベートフィールドは、MyWidgetを呼び出す前にデータ値を設定する「セッター」を介してのクライアントに公開できます。これにより、への呼び出しがトリガーされupdate()ます。MyWidgetpaintEvent()

于 2012-12-31T19:49:59.157 に答える
1

このプレイリストには、最高のQtチュートリアルが含まれています。チュートリアル74を開始すると(QpainterとQPen)、チュートリアル75はQRectを使用して長方形を描画する方法です。

于 2012-12-31T13:44:29.290 に答える
1

同様に@Matはあなたに言った:「イベント」は画家を立ち上げる正しい方法です。QPainterは、オブジェクトが描画される可能性のある安全な領域を運ぶ
QPaintEventイベントの後にのみ呼び出すことができます。

したがって、データを転送するための別の戦略を見つける必要があります。これは、多くの場合に調整できる簡単な方法を提案するのに役立ちます。

widget.cpp

#include <QtGui>
#include "widget.h"

#define MIN_DCX    (0.1)
#define MAX_DCX    (5.0)

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{    
    dcx=MIN_DCX;
    setFixedSize(170, 100);
}

void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event); 
    QPainter painter;
    painter.begin(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(Qt::black);
    pcx=dcx*2;
    QRect rect = QRect(50-dcx,25-dcx,60+pcx,40+pcx);
    painter.drawText(rect, Qt::AlignCenter,printData);
    painter.drawRect(rect);
    painter.end();

}

void Widget::setPrintData(QString value){
   printData = value;
   dcx=(dcx>MAX_DCX)?MIN_DCX:dcx+MIN_DCX;
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent);
    void setPrintData(QString value);

protected:
    void paintEvent(QPaintEvent *event);

private:
    QString printData;
    float dcx;
    float pcx;
};


#endif

window.cpp

#include <QtGui>
#include "widget.h"
#include "window.h"

#define MAX_SDCX  20

Window::Window()
    : QWidget()
{
    gobject = new Widget(this);

    textMode=1;
    rectMode=1;
    gobject->setPrintData(msgs[textMode]);

    QGridLayout *layout = new QGridLayout;
    layout->addWidget(gobject, 0, 0);
    setLayout(layout);

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

    setWindowTitle(tr("Rect Shaking"));
}



void Window::dataOnAir(){
    if((++rectMode)>MAX_SDCX){
        rectMode=0;
        textMode^=1;
    }
    gobject->setPrintData(msgs[textMode]);
    gobject->repaint();
}

window.h

#ifndef WINDOW_H
#define WINDOW_H

#include <QWidget>
#include "widget.h"

class Window : public QWidget
{
    Q_OBJECT

public:
    Window();

private slots:
    void dataOnAir();

private:
    Widget *gobject;
    const QString msgs[2] = {"Hello","World"};
    int textMode;
    int rectMode;
};

#endif

main.cpp

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

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Window window;
    window.show();
    return app.exec();
}

コードでわかるように、オブジェクト「ウィジェット」の外部でタイマーが実行されます

10ミリ秒ごとにウィジェットの再描画を送信して、異なるサイズの「長方形」を再描画し、20サイクル(200ミリ秒)ごとに「世界」のテキスト「こんにちは」を変更します

この例では、何らかの方法でQPainterDeviceアーキテクチャを上書きする必要があることがわかります。

また、「paintEvent 」内の「イベント」は無音で直接使用されていないことに気付くかもしれませんが、シーケンスQPainterを実行することが不可欠です。

于 2013-01-01T03:47:22.490 に答える
0

ウィジェットのpaintEvent()関数をオーバーライドすると、ウィジェットをカスタマイズできます。この関数は、ウィジェットを再描画するために定期的に呼び出されます。したがって、この関数で描画を行う必要があります。ただし、paintEvent()をオーバーライドすると、パフォーマンスの問題が発生する可能性があります。QGraphicsSceneとQGraphicsViewを使用したいのですが、この種の描画を行う一般的な方法である長方形をシーンに追加します。GraphicsViewFrameworkを確認してください

http://qt-project.org/doc/qt-4.8/graphicsview.html

于 2012-12-31T20:44:33.790 に答える