项目的需要,需要使用qt编写一个arm端的图形操作界面,完成雷达数据实时动态显示以及控制的功能,数据是自己模拟的,是xy坐标的点数据。先在window版本的qt上搭建简单框架测试通过,如下:
#-------------------------------------------------
#
# 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
#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();
}
#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
#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();
}
#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 */
#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();
}
}
}
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还有许多问题,比如数据传递的速度保证,实时阻塞性等,还有待进一步优化~。
更新,因为CSDN不常登录,我把文件上传到这里了//download.csdn.net/download/mp412c/12066377,需要的自行下载