3

「Draw」という名前の QPushButton、QLineEdit、および QFrame があるとします。ボタンをクリックすると、QLineEdit から数値を取得し、QFrame に円を描画します。これどうやってするの?コードを教えてください。

PS問題は、 QPainter の draw メソッドを drawEvent メソッドで呼び出す必要があることです。

4

3 に答える 3

11

@Kaleb Pedersonの答えがあなたにとって十分でない場合、ここにあなたが説明したものと一致する簡単なセットアップの完全な解決策があります. Linux 上の Qt 4.5.2 でテスト済み。暇だったのに…;)

main.cpp:

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

int main( int argc, char** argv )
{
    QApplication qapp( argc, argv );

    Window w;
    w.show();

    return qapp.exec();
}

window.h

#pragma once

class QLineEdit;
class QPushButton;
#include <QWidget>

class Frame;

class Window : public QWidget
{
Q_OBJECT

public:
    Window();

private slots:
    void onButtonClicked();

private:
    QLineEdit*   m_lineEdit;
    QPushButton* m_pushButton;
    Frame*       m_frame;
};

ウィンドウ.cpp:

#include <QHBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QVBoxLayout>

#include "frame.h"
#include "window.h"

Window::Window()
    : m_lineEdit  ( new QLineEdit( this ) )
    , m_pushButton( new QPushButton( tr( "Draw" ), this ) )
    , m_frame     ( new Frame( this ) )
{
    connect( m_pushButton, SIGNAL( clicked() )
           , SLOT( onButtonClicked() ) );

    QHBoxLayout*const hLayout = new QHBoxLayout;
    hLayout->addWidget( m_lineEdit );
    hLayout->addWidget( m_pushButton );

    QVBoxLayout*const vLayout = new QVBoxLayout( this );
    vLayout->addLayout( hLayout );
    m_frame->setFixedSize( 300, 400 );
    vLayout->addWidget( m_frame );

    setLayout( vLayout );
}

void Window::onButtonClicked()
{
    const int r = m_lineEdit->text().toInt(); // r == 0 if invalid
    m_frame->setCircleRadius( r );
    m_frame->update();
}

frame.h:

#pragma once

#include <QFrame>

class Frame : public QFrame
{
Q_OBJECT

public:
    Frame( QWidget* );

    void setCircleRadius( int );

protected:
    void paintEvent( QPaintEvent* );

private:
    int m_radius;
};

フレーム.cpp:

#include <QPainter>

#include "frame.h"

Frame::Frame( QWidget* parent )
    : QFrame( parent )
    , m_radius( 0 )
{
    setFrameStyle( QFrame::Box );
}

void Frame::setCircleRadius( int radius )
{
    m_radius = radius;
}

void Frame::paintEvent( QPaintEvent* pe )
{
    QFrame::paintEvent( pe );

    if ( m_radius > 0 )
    {
        QPainter p( this );
        p.drawEllipse( rect().center(), m_radius, m_radius );
    }
}
于 2010-07-22T15:47:31.773 に答える
3

フレームに描画を実行させたい場合は、何かを描画する必要があることを知る方法が必要なので、通知を受け取るスロットを作成します。

/* slot */ void drawCircle(QPoint origin, int radius) {
    addCircle(origin, radius);
    update(); // update the UI
}

void addCircle(QPoint origin, int radius) {
    circleList.add(new Circle(origin,radius));
}

paintEvent()次に、円を描画するためにオーバーライドする必要があるフレーム サブクラス:

void paintEvent(QPaintEvent *event) {
    QFrame::paintEvent(event);
    QPainter painter(this);
    foreach (Circle c, circleList) { // understand foreach requirements
        painter.drawEllipse(c.origin(), c.radius(), c.radius());
    }
}

ボタンのclicked()シグナルに応答するスロットが、正しい引数でスロットを呼び出すシグナルを発するdrawCircle限り、すべてが正しく機能するはずです。

于 2010-07-22T14:52:46.603 に答える
1

フレームに直接描画しません。
ここから始めてgraphicsview、最初は複雑に見えますが、GUI プログラムは最初に遭遇したときに大きな飛躍を遂げます

ほとんどの GUI (Qt、OpenGL など) では、プログラムで描画したい要素のリストを作成し、それらを何らかの方法で保存します。次に、コンピューターが画像を描画する必要があるときに呼び出される draw() 関数があります。それが移動されるか、別のウィンドウがその前に移動されます。次に、OnDraw または OnRepaint などの関数が呼び出され、オブジェクトのリストを描画する必要があります。

これを行う別の方法は、それらすべてを画像 (QOimage または QPixmap) に描画し、それを OnDraw または OnRepaint の画面にコピーすることです。たとえば、グラフィック パッケージに対してこれを行うことができます。

于 2010-07-22T14:17:49.837 に答える