2017-05-26 9 views
0

QPainterを使用してQtで簡単なアニメーションを作成しようとしていますが、現在はウィンドウで描画できましたが、同じことを定期的に描画する方法がわかりません。定期的にQPainterを使用した描画

は、ここに私の現在のコードです:

int main(int argc, char *argv[]){ 
QApplication a (argc, argv); 
QLabel l; 
Qpicture pi; 
Qpainter p(&pi); 
Qpen pen; 
/* 
Some ellipses and lines using p.drawLine and p.drawEllipse 
*/ 
p.end(); 
l.setPicture(pi); 
l.show(); 

return a.exec(); 

私はスレッドを作成しようとしましたが、私は、メインの外にはQApplicationを作成することはできませんし、私は私の画家、ラベル、画像やペンを与えることをしようとした場合彼らはプライベートなようスレッドは、それがコンパイルされません。

void PrintThread (QLabel * l, QPicture * pi, Qpainter * p, QPen * pen){ 
    /* 
    print lines and ellipses 
    */ 
} 

int main(int argc, char *argv[]){ 
QApplication a (argc, argv); 
    QLabel l; 
    Qpicture pi; 
    Qpainter p(&pi); 
    Qpen pen; 
std::thread doPaint (PrintThread, l, pi, p, pen); 
doPaint.join(); 

はどのようにすべてのXミリ秒を使用してQPainterのもの(ライン/楕円)を描画するサンプルコードは次のようになりますか?

+0

QTimerを使用して、タイマーが経過するたびにupdate関数を呼び出すことができます。 – dgrat

答えて

0

は私が最終的にaswellキー入力を読み取るためのサポートを追加し、クリーンソリューションに働い:

main.cppに

#include <QtWidgets> 
#include <QApplication> 
#include "screen.h" 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 

    screen Screen; 

    // size of your choice 
    Screen.setFixedSize(1024,576); 

    Screen.show(); 

    return a.exec(); 
} 

screen.h

#ifndef SCREEN_H 
#define SCREEN_H 

#include <QWidget> 
#include <QLabel> 

class screen : public QLabel 
{ 
    Q_OBJECT 

public: 
    screen(); 
    void keyPressEvent(QKeyEvent *); 
    void keyReleaseEvent(QKeyEvent *); 
public slots: 
    void tick(); 
}; 

#endif // SCREEN_H 

screen.cpp

#include "screen.h" 

#include <QtWidgets> 
#include <QTimer> 

QPen pen; 
QPicture pic; 
QPainter p; 

screen::screen(){ 

    QTimer * timer = new QTimer(); 
    connect(timer,SIGNAL(timeout()),this,SLOT(tick())); 

    timer->start(16); 
} 
void screen::keyPressEvent(QKeyEvent *event) 
{ 
    // event for key pressed 
} 

void screen::keyReleaseEvent(QKeyEvent *event) 
{ 
    // event for key released 
} 

void screen::tick(){ 
    p.begin(&pic); 

    // start draw 



    // finish draw 

    p.end(); 
    this->setPicture(pic); 
} 
2

この狂った病気には、人々が自動的に周期的/時限付きのタスクをマルチスレッドに関連付けることがあります。あなたは、並べ替えの何も必要ありません - ちょうどタイマーを使用します。

// https://github.com/KubaO/stackoverflown/tree/master/questions/picture-async-44201102 
#include <QtWidgets> 
#include <QtConcurrent> 

class PictureSource : public QObject { 
    Q_OBJECT 
public: 
    QPicture draw() { 
     QPicture pic; 
     QPainter p(&pic); 
     p.rotate(QTime::currentTime().msec()*360./1000.); 
     p.drawLine(0, 0, 50, 50); 
     pic.setBoundingRect({-50, -50, 100, 100}); 
     emit pictureChanged(pic); 
     return pic; 
    } 
    Q_SIGNAL void pictureChanged(const QPicture &); 
}; 
Q_DECLARE_METATYPE(QPicture) 

int main(int argc, char ** argv) { 
    QApplication app{argc, argv}; 
    qRegisterMetaType<QPicture>(); 
    QLabel label; 
    PictureSource source; 
    QObject::connect(&source, &PictureSource::pictureChanged, 
        &label, &QLabel::setPicture); 
    source.draw(); 
    label.show(); 
    QTimer timer; 
    timer.start(50); // every 50 ms 
    QObject::connect(&timer, &QTimer::timeout, &source, &PictureSource::draw); 
    return app.exec(); 
} 
#include "main.moc" 

- あなたがする必要があると思う場合 - あなたは、スレッドプールからワーカースレッドで描画を行うことができます。 draw()は、スレッドセーフであるか、そうでない場合は適切な同期せずにメインスレッドから同時にsourceオブジェクトを変更しないことをことを確認してください

QObject::connect(&timer, &QTimer::timeout, [&source]{ 
    auto pool = QThreadPool::globalInstance(); 
    QtConcurrent::run(pool, [&source]{ source.draw(); }); 
    }); 

:との接続を交換してください。

+0

もちろん、main.ocを見つけられないので、私のプロジェクトからmainwindow.ui(それを使用していなくても)を削除しなければならなかったようです。 – iv2b

+0

古いビルドフォルダがあります。コードまたはプロジェクトまたはビルドに問題があるかどうかが不明な場合は、ビルドを削除して、プロジェクトを最初に**再構築してください。 'mainwindow.ui'をこのプロジェクトに追加すると、うまくいくでしょう。また、エラーについては、作成中の実際のコードで実際のエラーを投稿するのに役立ちます。新しいビルドを最初に試していないと(つまり、古いビルドフォルダは存在しない)ほとんどの場合、時間が無駄です。 –

+0

注目してください、ありがとうございます! :) – iv2b

関連する問題