Я новичок в программировании Qt и объектно-ориентированном программировании, у меня есть некоторые знания C++, в основном с использованием микроконтроллеров для простых схем управления и аппаратного интерфейса для систем автоматизации.
Я пытаюсь использовать Qt для создания графического интерфейса для отображения строки, нарисованной из точек xy, хранящихся в массиве, и иметь возможность обновлять значения в массиве с помощью отдельного потока.
В настоящее время у меня очень простая программа, вычерчивающая строки из массива, но я не могу понять, как передавать обновленные значения этому массиву из main.cpp или из другого потока.
Я добавил свой код, как показано ниже.
// painterdialog.h
#ifndef PAINTERDIALOG_H
#define PAINTERDIALOG_H
#include <QDialog>
#include <QPainter>
namespace Ui {
class PainterDialog;
}
class PainterDialog : public QDialog
{
Q_OBJECT
public:
explicit PainterDialog(QWidget *parent = 0);
~PainterDialog();
private:
Ui::PainterDialog *ui;
protected:
void paintEvent(QPaintEvent *e);
};
#endif // PAINTERDIALOG_H
main.cpp ниже
#include "painterdialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
PainterDialog w;
w.show();
return a.exec();
}
painterdialog.cpp ниже
#include "painterdialog.h"
#include "ui_painterdialog.h"
PainterDialog::PainterDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::PainterDialog)
{
ui->setupUi(this);
}
PainterDialog::~PainterDialog()
{
delete ui;
}
void PainterDialog:: paintEvent(QPaintEvent *e)
{
int xVal[12] = {0,1,2,4,0,5,8,0,9,10,30,9999};
int yVal[12] = {0,1,2,5,0,7,7,0,8,20,10,9999};
QPainter MyPainter(this);
QPen PointPen(Qt::red);
PointPen.setWidth(5);
QPen LinePen(Qt::green);
LinePen.setWidth(2);
QPoint p1;
QPoint p2;
for(int x = 0; x<12 ; x++)
{
p1.setX(xVal[x]*10);
p1.setY(yVal[x]*10);
p2.setX(xVal[x+1]*10);
p2.setY(yVal[x+1]*10);
MyPainter.setPen(PointPen);
MyPainter.drawPoint(p1);
MyPainter.drawPoint(p2);
MyPainter.setPen(LinePen);
if(xVal[x]&&yVal[x] != 0 && xVal[x+1]&&yVal[x+1] !=0)//draw a connecting lines to points not going to the origin (infinity)
{
MyPainter.drawLine(p1, p2);
}
if(xVal[x+2]==9999)
{
break;
}
}
QPen LinePen2(Qt::black);
LinePen2.setStyle( Qt::DashDotLine );
LinePen2.setWidth(3);
MyPainter.setPen(LinePen2);
MyPainter.drawLine(QPoint(300,100), QPoint(100,200));
}
Я хотел бы использовать другой процесс для обновления значений внутри массива "xVal" и "yVal", мне кажется, мне нужно создать указатель на массив, который я постоянно обновляю значения, и передаю указатель на класс диалога художника.,
Я прошел несколько уроков и потратил немного времени на помощь на разных сайтах, но до сих пор ничего не придумал.
если кто-то может помочь, это будет очень полезно
Похоже, вы смешиваете термины "процесс" и "поток". Если вы имели в виду "нить", я предлагаю вам отредактировать ваш вопрос, потому что связь между потоками запрограммирована намного проще, чем общение между процессами.
Я думаю, что в вашем случае две основные концепции : класс QThread и механизм сигнала/слота. QThread используется для чтения данных x/y через Ethernet, а сигнал/слот используется для уведомления о том, что данные обновляются и должны быть перерисованы.
#include <QThread>
#include <QList>
#include <QPoint>
class DataFetcher : public QObject
{
Q_OBJECT
signals:
void dataChanged(QList<QPoint> data);
public slots:
void startFetching() {
//here you fill your data batch and pass it to PrinterDialog in GUI thread
/*cycle over data batches*/ {
QList<QPoint> data;
/*cycle over point in batch*/ {
QPoint p = ...; // take next point from your laser
data << p;
}
emit dataChanged(data);
}
}
};
В main.cpp:
#include "painterdialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
PainterDialog w;
w.show();
DataFetcher df;
QThread fetcherThread;
//to execute df slots in background thread
df.moveToThread(&fetcherThread);
//you'll need onDataChanged(QList<QPoint>) slot method and startDataFetching() signal in your Painter dialog
//wire up communication
QObject::connect(&df, &DataFetcher::dataChanged, &w, &PainterDialog::onDataChanged);
QObject::connect(&w, PainterDialog::startDataFetching, &df, &DataFetcher::startFetching);
//start background thread
fetcherThread.start();
//start GUI event loop
return a.exec();
//tell background thread that we are quiting
fetcherThread.quit();
//... and wait until background thread will finalize
fetcherThread.join();
}
Вам не нужно беспокоиться об удалении QList, пока вы передаете их по значению, а не указателем/ссылкой. QList на самом деле не более чем указатель с подсчетом ссылок (неявный обмен данными Qt).