一边做一边学一边摸索,终于基于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();
}