使用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

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();
}

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

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();
}

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 */

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();
        }
    }
}

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还有许多问题,比如数据传递的速度保证,实时阻塞性等,还有待进一步优化~。

展开阅读全文

没有更多推荐了,返回首页