Bootstrap

基于QT的简单大数据可视化模板

一边做一边学一边摸索,终于基于QT的数据大屏展板有了雏形,如下图,欢迎大家关注我,之后会持续更新。下面有全部代码,可以粘贴到自己的项目文档里慢慢研究。
在这里插入图片描述
目前为止本项目的难点在于可停靠窗口QDockWidget的设计,自定义窗口标题栏。

这个展板的小窗口应用QDockWidget,可以点击拖动出小窗口,并再嵌入主窗口中,也可以拖动DockWidget,使他们互相交换位置。

DockWidget的自带标题栏不好看,所以我将原来的标题栏删除后,自定义了一个标题栏,并进行配色,字体设计,之后也可以在现在代码的基础上进行再创造。

主窗口还可以继续添加可停靠窗口,几个小的可停靠窗口里面还可以继续布局新的控件。

不足:目前该项目在运行之后,几个窗口的大小分配不太合适。

本项目文件结构:

Project
	工程文件
		xxx.pro
	头文件
		title_bar.h
		widget.h
	源文件
		main.cpp
		title_bar.cpp
		widget.cpp

下面贴上代码:

xxx.pro

//在pro文件中只要在默认的情况下添加一行代码即可
QT       +=			charts

title_bar.h

//这个文件和title_bar.cpp文件还可以进一步优化,欢迎大家在评论区讨论
#ifndef TITLE_BAR
#define TITLE_BAR

#include <QWidget>

class QLabel;
class QPushButton;

class TitleBar : public QWidget
{
    Q_OBJECT

public:
    explicit TitleBar(QWidget *parent = 0);
    ~TitleBar();

protected:

    // 双击标题栏进行界面的最大化/还原
    virtual void mouseDoubleClickEvent(QMouseEvent *event);

    // 进行鼠界面的拖动
//    virtual void mousePressEvent(QMouseEvent *event);

    // 设置界面标题与图标
    virtual bool eventFilter(QObject *obj, QEvent *event);

private slots:

    // 进行最小化、最大化/还原、关闭操作
//    void onClicked();

private:

    // 最大化/还原
//    void updateMaximize();

private:
    QLabel *m_pIconLabel;
    QLabel *m_pTitleLabel;

};

#endif // TITLE_BAR

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QtCharts/QChartGlobal>
#include <QtWidgets/QWidget>
#include <QtWidgets/QDockWidget>
#include <QLineSeries>
#include <QVBoxLayout>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

QT_CHARTS_BEGIN_NAMESPACE
class QChartView;
class QChart;
QT_CHARTS_END_NAMESPACE

QT_CHARTS_USE_NAMESPACE//此句必备


class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
private:
    QChart *creatDonutChart() const;
    QChart *creatBarChart() const;
    QChart *creatLineChart() const;
    QChart *creatAreaChart() const;
    QDockWidget *pd1,*pd2,*pd3,*pd4;
    QMainWindow *pw;
    QWidget *pw1,*pw2;
    QDockWidget *m_titlebar(QDockWidget *pd,QWidget *m_chart,QString m_str) ;

private:
//    void mousePressEvent(QMouseEvent *e);
//    void mouseMoveEvent(QMouseEvent *e);
//    QPoint lastPos;



};
#endif // WIDGET_H

title_bar.cpp

#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <QEvent>
#include <QMouseEvent>
#include <QApplication>
#include "title_bar.h"
#include <qt_windows.h>


TitleBar::TitleBar(QWidget *parent)
    : QWidget(parent)
{
    setFixedHeight(30);


    m_pTitleLabel = new QLabel(this);

    m_pTitleLabel->setFixedHeight(30);
    m_pTitleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);


    m_pTitleLabel->setObjectName("whiteLabel");


    m_pTitleLabel->setContentsMargins(0,0,0,0);
    m_pTitleLabel->setAlignment(Qt::AlignCenter);

    //设置字颜色
    QPalette pa;
    pa.setColor(QPalette::WindowText,Qt::white);
    m_pTitleLabel->setPalette(pa);
    //设置字号
    QFont ft("微软雅黑");
    ft.setPointSize(10);
    m_pTitleLabel->setFont(ft);


    QHBoxLayout *mainWidgetLayout = new QHBoxLayout(this);
    QWidget *mainWidget = new QWidget;
    QHBoxLayout *pLayout = new QHBoxLayout;

    mainWidgetLayout->addWidget(mainWidget);
    mainWidget->setLayout(pLayout);
    mainWidgetLayout->setMargin(0);
    pLayout->setContentsMargins(0,0,0,0);
    pLayout->setSpacing(0);
    mainWidget->setStyleSheet("QWidget{background-color:rgb(48, 48, 85);}");
    pLayout->addWidget(m_pTitleLabel);



}

TitleBar::~TitleBar()
{

}

void TitleBar::mouseDoubleClickEvent(QMouseEvent *event)
{
    Q_UNUSED(event);

    event->ignore();
}



bool TitleBar::eventFilter(QObject *obj, QEvent *event)
{
    switch (event->type())
    {
    case QEvent::WindowTitleChange:
    {
        QWidget *pWidget = qobject_cast<QWidget *>(obj);
        if (pWidget)
        {
            m_pTitleLabel->setText(pWidget->windowTitle());
            return true;
        }
    }

     default:
         return QWidget::eventFilter(obj, event);

     }
     return QWidget::eventFilter(obj, event);
}

//void TitleBar::onClicked()
//{
//    QPushButton *pButton = qobject_cast<QPushButton *>(sender());
//    QWidget *pWindow = this->window();
//    if (pWindow->isTopLevel())
//    {

//    }
//}

widget.cpp

#include "widget.h"
#include <QtCharts/QChartView>
#include <QtCharts/QPieSeries>
#include <QtCharts/QPieSlice>
#include <QtWidgets/QGridLayout>
#include <QBarSet>
#include <QBarSeries>
#include <QBarCategoryAxis>
#include <QMainWindow>
#include <QLineSeries>
#include <QVBoxLayout>
#include <QPixmap>
#include <QIcon>
#include <QTableWidget>
#include <QPushButton>
#include <QLabel>
#include<QDockWidget>
#include "title_bar.h"
#include <QtCharts/QAreaSeries>
#include <QMouseEvent>

Widget::Widget(QWidget *parent)
    : QWidget(parent)

{

/********************配色*****************/
    QMainWindow *pw = new QMainWindow;
//    QPalette palette = this->palette();
//    palette.setColor(QPalette::Window, QColor(4, 7, 38));  //改变控件背景色
//    this->setPalette(palette);




/*********************************布局*********************************/
//    QGridLayout *baseLayout = new QGridLayout();//布局管理器
/**********************设置可停靠窗口******************/
    QDockWidget *pd1 = new QDockWidget;
    QDockWidget *pd2 = new QDockWidget;
    QDockWidget *pd3 = new QDockWidget;

    pw->addDockWidget(Qt::RightDockWidgetArea,pd1);
    pw->addDockWidget(Qt::BottomDockWidgetArea,pd2);
    pw->addDockWidget(Qt::LeftDockWidgetArea,pd3);

    pd1->setAllowedAreas(Qt::RightDockWidgetArea|Qt::BottomDockWidgetArea|Qt::LeftDockWidgetArea );//设置顶部不可停靠
    pd2->setAllowedAreas( Qt::BottomDockWidgetArea|Qt::RightDockWidgetArea|Qt::LeftDockWidgetArea );
    pd3->setAllowedAreas( Qt::BottomDockWidgetArea|Qt::RightDockWidgetArea|Qt::LeftDockWidgetArea );

    pw->setDockOptions(QMainWindow::AnimatedDocks);//设置停靠参数,不允许重叠,只允许拖动

/********************Creating Donutchart*****************/
//可停靠窗口1
    QChartView *chartView;
    chartView=new QChartView(creatDonutChart());
    chartView->setRenderHint(QPainter::Antialiasing);//渲染抗锯齿
    //以下代码可以实现在一个DockWidget中显示多个chart,直接在nn后面addwidget即可
    QWidget *mm = new QWidget();
    QGridLayout *nn = new QGridLayout();
    nn->addWidget(chartView);
    mm->setLayout(nn);
    pd1->setWidget(mm);
    pd1=m_titlebar(pd1,chartView,"Donutchart Chart");


//*******************Creating Bar Chart*********************//
//可停靠窗口2
    chartView=new QChartView(creatBarChart());
    chartView->setRenderHint(QPainter::Antialiasing);//渲染抗锯齿
    //以下代码可以实现在一个DockWidget中显示多个chart,直接在nn后面addwidget即可
    mm = new QWidget();
    nn = new QGridLayout();
    nn->addWidget(chartView);
    mm->setLayout(nn);
    pd2->setWidget(mm);
    pd2=m_titlebar(pd2,chartView,"Bar Chart");

/********************Creating Line Chart************************/


/*************************AreaChart Example*************************/
//可停靠窗口3
    chartView = new QChartView(creatAreaChart());
    chartView->setRenderHint(QPainter::Antialiasing);
    //以下代码可以实现在一个DockWidget中显示多个chart,直接在nn后面addwidget即可
    mm = new QWidget();
    nn = new QGridLayout();
    nn->addWidget(chartView);
    mm->setLayout(nn);
    pd3->setWidget(mm);
    pd3=m_titlebar(pd3,chartView,"AreaChart");


/**************************主窗口****************************/
    chartView=new QChartView(creatLineChart());
    chartView->setRenderHint(QPainter::Antialiasing);
    pw->setCentralWidget(chartView);


/*************************大屏显示**************************/
    pw->setWindowFlags (Qt::FramelessWindowHint);//去掉标题栏,但不能鼠标缩放窗口
    pw->showFullScreen();

}

Widget::~Widget()
{

}

QChart *Widget::creatDonutChart() const
{
    QPieSeries *series=new QPieSeries();
    series->setHoleSize(0.35);//圆孔大小
    series->append("Protein 4.2%",4.2);


    QPieSlice *slice=series->append("Fat 15.6%",15.6);//单个切片
    slice->setExploded();//使该切片突出
    slice->setLabelVisible();//显示切片的标签
    series->append("Other 23.8%", 23.8);
    series->append("Carbs 56.4%", 56.4);//若以圆心为原点,作xoy坐标系,则以y轴为起始轴,圆环的每一小部分按照编程顺序顺时针排列。
    QChart *chart = new QChart;
    chart->setTitle("Donut with a lemon glaze (100g)");
    chart->addSeries(series);
    chart->legend()->setAlignment(Qt::AlignBottom);//图例放在底部
    chart->setTheme(QChart::ChartThemeBlueCerulean);//主题颜色设置为天然色
    chart->legend()->setFont(QFont("Arial",7));//图例字体宋体7号字

    //标题栏

    return chart;
}
QChart *Widget::creatBarChart() const
{
    //本示例要展示五个人在每个月的某项数据,比如每个月掉多少头发
    //创建要展示的对象,本示例中是姓名,并设置不同对象在每个月的数据
    QBarSet *set0 = new QBarSet("Jane");
    QBarSet *set1 = new QBarSet("John");
    QBarSet *set2 = new QBarSet("Axel");
    QBarSet *set3 = new QBarSet("Mary");
    QBarSet *set4 = new QBarSet("Sama");
    *set0<<1<<2<<3<<4<<5<<6;
    *set1<<3<<7<<6<<5<<5<<2;
    *set2<<2<<8<<1<<3<<6<<5;
    *set3<<1<<3<<5<<7<<1<<6;
    *set4<<4<<3<<3<<6<<7<<2;
    //创建一个序列对象,并将上面的数据添加到序列中
    QBarSeries *bseries = new QBarSeries();
    bseries->append(set0);
    bseries->append(set1);
    bseries->append(set2);
    bseries->append(set3);
    bseries->append(set4);
    //创建一个QChart类的对象chart,并将series对象加入到chart中
    QChart *chart = new QChart();
    chart->addSeries(bseries);
    //设置标题和动画
    chart->setTitle("simple chart example");
    chart->setAnimationOptions(QChart::SeriesAnimations);//设置动画

    //创建坐标
    //首先创建一个字符串列表,作为横坐标
    QStringList *categories = new QStringList();
    *categories<<"Jane"<<"Feb"<<"Mar"<<"Apr"<<"May"<<"Jun";
    //创建一个类别轴对象
    QBarCategoryAxis *axis = new QBarCategoryAxis();
    axis->append(*categories);//添加横坐标,月份
    chart->createDefaultAxes();//设置默认坐标轴,虽然后面的设置会覆盖默认坐标轴,但是也要在后面设置之前进行初始设置
    chart->setAxisX(axis,bseries);//将类别轴对象(横坐标月)和序列对象(每个月的数据)作为参数,设置X轴。

    //设置图例
    chart->legend()->setVisible(true);//图例可见
    chart->legend()->setAlignment(Qt::AlignBottom);//将图例放在表底
    chart->setTheme(QChart::ChartThemeBlueCerulean);//主题颜色设置为天然色
    return chart;
}

QChart *Widget::creatLineChart() const
{
    QLineSeries *series=new QLineSeries();
    series->append(0,0);
    series->append(1,1);
    series->append(2,4);
    series->append(3,9);
    series->append(4,7);
    *series<<QPointF(11,1)<<QPointF(13,3)<<QPointF(17,6)<<QPointF(18, 3) << QPointF(20, 2);
    //QPointF功能与append相同,也是添加一些点


    //创建一个QChart对象chart,并将series放入chart中
    QChart *chart=new QChart();
    chart->legend()->hide();//隐藏图例
    chart->addSeries(series);
    chart->createDefaultAxes();
    chart->setTitle("linechart测试示例");
    chart->setTheme(QChart::ChartThemeBlueCerulean);//主题颜色设置为天然色

    return chart;

}

QChart *Widget::creatAreaChart() const
{//参考帮助文档源码
    QLineSeries *series0 = new QLineSeries();
    QLineSeries *series1 = new QLineSeries();

    *series0 << QPointF(1, 5) << QPointF(3, 7) << QPointF(7, 6) << QPointF(9, 7) << QPointF(12, 6)
             << QPointF(16, 7) << QPointF(18, 5);
    *series1 << QPointF(1, 3) << QPointF(3, 4) << QPointF(7, 3) << QPointF(8, 2) << QPointF(12, 3)
             << QPointF(16, 4) << QPointF(18, 3);

    QAreaSeries *series = new QAreaSeries(series0, series1);
    series->setName("Batman");
    QPen pen(0x059605);
    pen.setWidth(3);
    series->setPen(pen);

    QLinearGradient gradient(QPointF(0, 0), QPointF(0, 1));
    gradient.setColorAt(0.0, 0x3cc63c);
    gradient.setColorAt(1.0, 0x26f626);
    gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
    series->setBrush(gradient);

    QChart *chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("Simple areachart example");
    chart->createDefaultAxes();
    chart->axisX()->setRange(0, 20);
    chart->axisY()->setRange(0, 10);
    chart->setTheme(QChart::ChartThemeBlueCerulean);//主题颜色设置为天然色

    return chart;

}
QDockWidget *Widget::m_titlebar(QDockWidget *pd,QWidget * m_chart,QString m_str)
{

    /******************************自定义标题栏********************/
        TitleBar *pTitleBar = new TitleBar(m_chart);
        pd->installEventFilter(pTitleBar);
        pd->setWindowTitle(m_str);
        pd->setTitleBarWidget(pTitleBar);

        return pd;
}
/************************窗口移动*********************/
/*在取消标题栏后,无法对窗口进行拖拽,这里对鼠标点击和移动事件进行重写*/
//void Widget::mousePressEvent(QMouseEvent *e) // 鼠标点击事件
//{
//    this->lastPos = e->globalPos();
//}
//void Widget::mouseMoveEvent(QMouseEvent *e) // 鼠标移动事件
//{
//    int xLen = e->globalX() - lastPos.x();
//    int yLen = e->globalY() - lastPos.y();
//    this->lastPos = e->globalPos();
//    move(x()+xLen, y()+yLen); // 移动窗口
//}

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
//    w.show();
//    a.setPalette();
    QPalette palette = a.palette();
    palette.setColor(QPalette::Window, QColor(4, 7, 38));  //改变控件背景色
    a.setPalette(palette);

    return a.exec();
}

;