我正在尝试通过QPainter在Qt中创建一个简单的动画,目前我已经可以在我的窗口中绘制,但我无法弄清楚如何定期绘制相同的东西。
这是我目前的代码:
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();
我已经尝试创建一个线程,但是我无法在main之外创建一个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 :(得分: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"
现在 - 如果您认为需要 - 您可以从线程池中的工作线程中进行绘制。用以下内容替换连接:
QObject::connect(&timer, &QTimer::timeout, [&source]{
auto pool = QThreadPool::globalInstance();
QtConcurrent::run(pool, [&source]{ source.draw(); });
});
确保draw()
是线程安全的,或者您没有在没有正确同步的情况下从主线程同时修改source
对象。
答案 1 :(得分:0)
我最终选择了干净解决方案,增加了对阅读按键的支持:
的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);
}