使用QT5完成一个数据实时显示控制的Demo
项目的需要,需要使用qt编写一个arm端的图形操作界面,完成雷达数据实时动态显示以及控制的功能,数据是自己模拟的,是xy坐标的点数据。先在window版本的qt上搭建简单框架测试通过,如下:
TestUiTheme-pro
#-------------------------------------------------
#
# Project created by 西电1603-WYC 2018-12-13T16:12:18
#
#-------------------------------------------------
QT += core gui
QT += charts
requires(qtConfig(combobox))
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = TestUiTheme
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
target.path = $$[QT_INSTALL_EXAMPLES]/charts/chartthemes
INSTALLS += target
SOURCES += main.cpp\
mainwindow.cpp \
themewidget.cpp
HEADERS += mainwindow.h \
themewidget.h
FORMS += mainwindow.ui \
themewidget.ui
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "themewidget.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QList<float> daa;
QList<float> daas;
int dd;
int dds;
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
public slots:
void handleTimeout();
private:
Ui::MainWindow *ui;
themeWidget *xx;
QTimer *m_timer;
};
#endif // MAINWINDOW_H
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QTimer"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
dd = 1,dds = 1;
xx = ui->widget;
m_timer = new QTimer(this);
m_timer->setSingleShot(false);
connect(m_timer,SIGNAL(timeout()),this,SLOT(handleTimeout()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
for(int s = 0;s<10;s++){
daa.append(s*1.0*dd);
}
QList<float>::iterator iter;
for(iter = daa.begin();iter != daa.end();iter+=2){
ui->textBrowser->append(QString("%1").arg(*iter)+","+QString("%1").arg(*iter+1));
}
dd++;
xx->fromMain(daa);
}
void MainWindow::on_pushButton_2_clicked()
{
ui->textBrowser->setPlainText("");
daa.clear();
daas.clear();
xx->clearALL();
}
void MainWindow::on_pushButton_3_clicked()
{
m_timer->start(2*1000);
}
void MainWindow::handleTimeout(){
for(int s = 0;s<2;s++){
daas.append((s+dds)*1.0*dds);
}
ui->textBrowser->setPlainText("");
QList<float>::iterator iter;
for(iter = daas.begin();iter != daas.end();iter+=2){
ui->textBrowser->append(QString("%1").arg(*iter)+","+QString("%1").arg(*iter+1));
}
dds++;
xx->fromMain(daas);
}
void MainWindow::on_pushButton_4_clicked()
{
m_timer->stop();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
themewidget.h
#ifndef THEMEWIDGET_H
#define THEMEWIDGET_H
#include <QtWidgets/QWidget>
#include <QtCharts/QChartGlobal>
#include <QtCharts/QSplineSeries>
#include <QtCharts/QScatterSeries>
class QComboBox;
class QCheckBox;
class Ui_ThemeWidgetForm;
QT_CHARTS_BEGIN_NAMESPACE
class QChartView;
class QChart;
QT_CHARTS_END_NAMESPACE
typedef QPair<QPointF, QString> Data;
typedef QList<Data> DataList;
typedef QList<DataList> DataTable;
QT_CHARTS_USE_NAMESPACE
class themeWidget: public QWidget
{
Q_OBJECT
public:
explicit themeWidget(QWidget *parent = 0);
~themeWidget();
QList<float> skt11;
void fromMain(QList<float>);
void clearALL();
QChartView *chartView;
QChart *a1;
QSplineSeries *series1 ;
QChart *a2;
QScatterSeries *series2 ;
float XM;
float YM;
private Q_SLOTS:
void updateUI();
private:
DataTable inputData(QList<float> data);
void populateThemeBox();
void populateAnimationBox();
void populateLegendBox();
void connectSignals();
void addData(DataTable hh , QChart *ff);
//QChart *createSplineChart() ;
void createSplineChart(QChart *chaaat) ;
void createScatterChart(QChart *chbbbt);
private:
int m_listCount;
int X_Max;
int Y_Max;
QList<QChartView *> m_charts;
DataTable m_dataTable;
Ui_ThemeWidgetForm *m_ui;
};
#endif /* THEMEWIDGET_H */
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
themewidget.cpp
#include "themewidget.h"
#include "ui_themewidget.h"
#include <QtCharts/QChartView>
#include <QtCharts/QPieSeries>
#include <QtCharts/QPieSlice>
#include <QtCharts/QAbstractBarSeries>
#include <QtCharts/QPercentBarSeries>
#include <QtCharts/QStackedBarSeries>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QLineSeries>
#include <QtCharts/QSplineSeries>
#include <QtCharts/QScatterSeries>
#include <QtCharts/QAreaSeries>
#include <QtCharts/QLegend>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QFormLayout>
#include <QtWidgets/QComboBox>
#include <QtWidgets/QSpinBox>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QLabel>
#include <QtCharts/QBarCategoryAxis>
#include <QtWidgets/QApplication>
#include <QtCharts/QValueAxis>
themeWidget::themeWidget(QWidget *parent) :
QWidget(parent),
m_listCount(1),
X_Max(10),
Y_Max(10),
m_ui(new Ui_ThemeWidgetForm)
//m_ui(new Ui::themeWidget)
{
XM=X_Max;YM=Y_Max;
m_ui->setupUi(this);
populateThemeBox();
populateAnimationBox();
populateLegendBox();
for(int s = 0;s<10;s++){
skt11.append(0);
}
m_dataTable=inputData(skt11);
//create charts
a1 = new QChart();
series1 = new QSplineSeries(a1);
createSplineChart(a1);
chartView = new QChartView(a1);
m_ui->gridLayout->addWidget(chartView,2,1);
m_charts << chartView;
a2 = new QChart();
series2 = new QScatterSeries(a2);
createScatterChart(a2);
chartView = new QChartView(a2);
m_ui->gridLayout->addWidget(chartView, 2,2);
m_charts << chartView;
// Set defaults
m_ui->antialiasCheckBox->setChecked(true);
// Set the colors from the light theme as default ones
QPalette pal = qApp->palette();
pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
pal.setColor(QPalette::WindowText, QRgb(0x404044));
qApp->setPalette(pal);
updateUI();
}
themeWidget::~themeWidget()
{
delete m_ui;
}
void themeWidget::clearALL(){
for (const DataList &list : m_dataTable) {
for (const Data &data : list){
series1->remove(data.first);
series2->remove(data.first);
}
}
}
void themeWidget::addData(DataTable hh , QChart *ff){
QString name("Series ");
int nameIndex = 0;
for (const DataList &list : hh) {
//QSplineSeries *series = new QSplineSeries(chart);
for (const Data &data : list){
series1->append(data.first);
series2->append(data.first);
}
series1->setName(name + QString::number(nameIndex));
series2->setName(name + QString::number(nameIndex));
nameIndex++;
}
a1->axes(Qt::Horizontal).first()->setRange(0, XM);
a1->axes(Qt::Vertical).first()->setRange(0, YM);
a2->axes(Qt::Horizontal).first()->setRange(0, XM);
a2->axes(Qt::Vertical).first()->setRange(0, YM);
}
void themeWidget::fromMain(QList<float> dd){
m_dataTable=inputData(dd);
addData(m_dataTable , a1);
}
DataTable themeWidget::inputData(QList<float> data)
{
DataTable dataTable;
int listCount = 1;
for (int i(0); i < listCount; i++) {
DataList dataList;
for (int j(0); j < data.count(); j+=2) {
if(data.at(j)>XM){XM = data.at(j);}
if(data.at(j+1)>YM){YM = data.at(j+1);}
YM = data.at(j+1);
QPointF value(data.at(j),data.at(j+1));
QString label = "Slice " + QString::number(i) + ":" + QString::number(j);
dataList << Data(value, label);
}
dataTable << dataList;
}
return dataTable;
}
void themeWidget::populateThemeBox()
{
// add items to theme combobox
m_ui->themeComboBox->addItem("Light", QChart::ChartThemeLight);
m_ui->themeComboBox->addItem("Blue Cerulean", QChart::ChartThemeBlueCerulean);
m_ui->themeComboBox->addItem("Dark", QChart::ChartThemeDark);
m_ui->themeComboBox->addItem("Brown Sand", QChart::ChartThemeBrownSand);
m_ui->themeComboBox->addItem("Blue NCS", QChart::ChartThemeBlueNcs);
m_ui->themeComboBox->addItem("High Contrast", QChart::ChartThemeHighContrast);
m_ui->themeComboBox->addItem("Blue Icy", QChart::ChartThemeBlueIcy);
m_ui->themeComboBox->addItem("Qt", QChart::ChartThemeQt);
}
void themeWidget::populateAnimationBox()
{
// add items to animation combobox
m_ui->animatedComboBox->addItem("No Animations", QChart::NoAnimation);
m_ui->animatedComboBox->addItem("GridAxis Animations", QChart::GridAxisAnimations);
m_ui->animatedComboBox->addItem("Series Animations", QChart::SeriesAnimations);
m_ui->animatedComboBox->addItem("All Animations", QChart::AllAnimations);
}
void themeWidget::populateLegendBox()
{
// add items to legend combobox
m_ui->legendComboBox->addItem("No Legend ", 0);
m_ui->legendComboBox->addItem("Legend Top", Qt::AlignTop);
m_ui->legendComboBox->addItem("Legend Bottom", Qt::AlignBottom);
m_ui->legendComboBox->addItem("Legend Left", Qt::AlignLeft);
m_ui->legendComboBox->addItem("Legend Right", Qt::AlignRight);
}
void themeWidget::createSplineChart(QChart *chaaat)
{
chaaat->setTitle("Spline chart");
QString name("Series ");
int nameIndex = 0;
for (const DataList &list : m_dataTable) {
for (const Data &data : list)
series1->append(data.first);
series1->setName(name + QString::number(nameIndex));
nameIndex++;
chaaat->addSeries(series1);
}
chaaat->createDefaultAxes();
chaaat->axes(Qt::Horizontal).first()->setRange(0, X_Max);
chaaat->axes(Qt::Vertical).first()->setRange(0, Y_Max);
// Add space to label to add space between labels and axis
QValueAxis *axisY = qobject_cast<QValueAxis*>(chaaat->axes(Qt::Vertical).first());
Q_ASSERT(axisY);
axisY->setLabelFormat("%.1f ");
}
void themeWidget::createScatterChart(QChart *chbbbt)
{
// scatter chart
chbbbt->setTitle("Scatter chart");
QString name("Series ");
int nameIndex = 0;
for (const DataList &list : m_dataTable) {
for (const Data &data : list)
series2->append(data.first);
series2->setName(name + QString::number(nameIndex));
nameIndex++;
chbbbt->addSeries(series2);
}
chbbbt->createDefaultAxes();
chbbbt->axes(Qt::Horizontal).first()->setRange(0, X_Max);
chbbbt->axes(Qt::Vertical).first()->setRange(0, Y_Max);
// Add space to label to add space between labels and axis
QValueAxis *axisY = qobject_cast<QValueAxis*>(chbbbt->axes(Qt::Vertical).first());
Q_ASSERT(axisY);
axisY->setLabelFormat("%.1f ");
}
void themeWidget::updateUI()
{
QChart::ChartTheme theme = static_cast<QChart::ChartTheme>(
m_ui->themeComboBox->itemData(m_ui->themeComboBox->currentIndex()).toInt());
const auto charts = m_charts;
if (!m_charts.isEmpty() && m_charts.at(0)->chart()->theme() != theme) {
for (QChartView *chartView : charts) {
chartView->chart()->setTheme(theme);
}
// Set palette colors based on selected theme
QPalette pal = window()->palette();
if (theme == QChart::ChartThemeLight) {
pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
pal.setColor(QPalette::WindowText, QRgb(0x404044));
} else if (theme == QChart::ChartThemeDark) {
pal.setColor(QPalette::Window, QRgb(0x121218));
pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
} else if (theme == QChart::ChartThemeBlueCerulean) {
pal.setColor(QPalette::Window, QRgb(0x40434a));
pal.setColor(QPalette::WindowText, QRgb(0xd6d6d6));
} else if (theme == QChart::ChartThemeBrownSand) {
pal.setColor(QPalette::Window, QRgb(0x9e8965));
pal.setColor(QPalette::WindowText, QRgb(0x404044));
} else if (theme == QChart::ChartThemeBlueNcs) {
pal.setColor(QPalette::Window, QRgb(0x018bba));
pal.setColor(QPalette::WindowText, QRgb(0x404044));
} else if (theme == QChart::ChartThemeHighContrast) {
pal.setColor(QPalette::Window, QRgb(0xffab03));
pal.setColor(QPalette::WindowText, QRgb(0x181818));
} else if (theme == QChart::ChartThemeBlueIcy) {
pal.setColor(QPalette::Window, QRgb(0xcee7f0));
pal.setColor(QPalette::WindowText, QRgb(0x404044));
} else {
pal.setColor(QPalette::Window, QRgb(0xf0f0f0));
pal.setColor(QPalette::WindowText, QRgb(0x404044));
}
window()->setPalette(pal);
}
// Update antialiasing
bool checked = m_ui->antialiasCheckBox->isChecked();
for (QChartView *chart : charts)
chart->setRenderHint(QPainter::Antialiasing, checked);
// Update animation options
QChart::AnimationOptions options(
m_ui->animatedComboBox->itemData(m_ui->animatedComboBox->currentIndex()).toInt());
if (!m_charts.isEmpty() && m_charts.at(0)->chart()->animationOptions() != options) {
for (QChartView *chartView : charts)
chartView->chart()->setAnimationOptions(options);
}
// Update legend alignment
Qt::Alignment alignment(
m_ui->legendComboBox->itemData(m_ui->legendComboBox->currentIndex()).toInt());
if (!alignment) {
for (QChartView *chartView : charts)
chartView->chart()->legend()->hide();
} else {
for (QChartView *chartView : charts) {
chartView->chart()->legend()->setAlignment(alignment);
chartView->chart()->legend()->show();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
ui界面我就不上传代码了,具体看效果图:
生成数据模拟项目中手动载入数据,每次载入5个点(可设置),并显示,且可以clear。
生成持续数据模拟项目中DSP持续传过来的数据,这里是使用一个Qtimer来完成模拟的,每次传过来一个点并更新图表。
此demo是在学习QT官方的QChart实例的基础上一步步修改的,由于原来的例子还带了UI颜色选择,发现还不错,就保留下来了,可以选择各个“皮肤”,都是免费的:) :)
这个demo的的themeWidget类是单独写出了,然后在mainWindow里面新建了一个WIdget后提升类后完成融合的。
总结
我觉得这样设计把控制和显示解耦和分开会比较清晰,事实的确如此,这里需要主要一个,mainwindow向themeWidget是属于父类向子类传值,我并没有使用信号和槽,而是参照https://blog.csdn.net/shihoongbo/article/details/48681979的讲解第三中方法,调用公有函数传递过去的,但是和他的例子不一样的是,我这里的widget并不是单独的窗口类,他是包含在mainwindow里面且独立的子类,也就是说mainWindow类实例化的时候它的一个实例也new了,所以如果像他讲的 xx = new themeWidget;就会发现传不过去值,因为你传递去的是再一次new的一个子类,而不是mainWIndow里面实例化的那个,当然也就无法再界面里显示传过来的数据,所以需要改成xx = ui->widget;即可。
当然,这个demo还有许多问题,比如数据传递的速度保证,实时阻塞性等,还有待进一步优化~。