一边做一边学一边摸索,终于基于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 #includeclass 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#include #include #include #include #include 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#include #include #include #include #include #include "title_bar.h" #include 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 (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 (sender()); // QWidget *pWindow = this->window(); // if (pWindow->isTopLevel()) // { // } //}
widget.cpp
#include "widget.h" #include#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "title_bar.h" #include #include 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);//设置停靠参数,不允许重叠,只允许拖动 //可停靠窗口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"); // //可停靠窗口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"); //可停靠窗口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< 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" #includeint 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(); }



