日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

20200511-01 基于 QCustomPlot 移植到 QML 上(qt.514)

發布時間:2023/12/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 20200511-01 基于 QCustomPlot 移植到 QML 上(qt.514) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

源碼下載

一:要點說明

1. replot() 界面刷新(需要單獨調用)

replot() 這個函數的作用是用于刷新顯示界面,根據文檔顯示,刷新的方式總共有 4 中:

rpImmediateRefresh 立即全局更新(先立即重繪表格,然后調用 QWidget::repaint() 重繪整個 widgetrpQueuedRefresh 依次更新(先立即重繪表格,然后調用 QWidget::update() 進行更新,避免多次 repaint() 消耗資源)rpRefreshHint (默認)取決于 hint 是否被設置為 QCP::phImmediaRefresh,可以查看 setPlottingHints)rpQueuedReplot 整個更新事件循環進行,以避免沒有意義的重復更新

所以在作者使用中,采用 300ms 執行一次 replot(QCustomPlot::RefreshPriority::rpQueuedReplot) 進行界面更新

在測試中,IMX6UL, 500M CPU 資源占用率(不是特別高,沒有單獨計算僅在個人寫的APP上為40-50之間波動)

?

2. 清除函數

似乎沒有找到單獨可以調用的函數,所以使用 setData() 函數代替

void clear_all(){//getPlot() 就是用來獲取 QCustomPlot 指針getPlot()->graph(0)->setData(QVector<double>(), QVector<double>());getPlot()->replot();}

3. 單獨加點

void append_data(const double& key, const double& val){getPlot()->graph(0)->addData(key, val);}

?

4. QQuickPaintItem

提供了在 QML 上繪制的 QPainter API,可以將 QWidget 或者自定義控件繪制到 QML 界面上,需要實現 paint() , 如果需要在控件上實現其他功能,比如鼠標功能,可以具體查看 QQuickItem 類中的虛擬函數定義


二:源碼 (代碼格式參考網上信息)

//ProFile #需要添加 QT += quick qml printsupport core//main.cpp QApplication app(argc, argv); //使用這個來代替 QCoreApplication 等默認創建的 application qmlRegisterType <QCustomLine> ("DataModel", 1, 0, "ChartModel_Test");//main.qml 注意使用 ApplicationWindow{} 來代替 Window() // qcustomchart.h #include <QtQuick>class QCustomPlot; class QCPAbstractPlottable;class QCustomChart : public QQuickPaintedItem { Q_OBJECT public: explicit QCustomChart(QQuickItem *parent = nullptr); virtual ~QCustomChart();void paint(QPainter *painter) override; virtual void initChartUI(){};QCustomPlot *getPlot();protected:virtual void mousePressEvent( QMouseEvent* event ) override; virtual void mouseReleaseEvent( QMouseEvent* event ) override; virtual void mouseMoveEvent( QMouseEvent* event ) override; virtual void mouseDoubleClickEvent( QMouseEvent* event ) override; virtual void wheelEvent( QWheelEvent *event ) override;void routeMouseEvents( QMouseEvent* event ); void routeWheelEvents( QWheelEvent* event );public slots: void onChartViewReplot(); void updateChartViewSize(); private: QCustomPlot* mCustomPlot {nullptr}; };//qcustomchart.cpp #include "qcustomchart.h" #include "qcustomplot.h" #include <QDebug>QCustomChart::QCustomChart(QQuickItem *parent) : QQuickPaintedItem(parent), mCustomPlot(new QCustomPlot()) { setFlag(QQuickItem::ItemHasContents, true); setAcceptedMouseButtons(Qt::AllButtons); setAcceptHoverEvents(true);connect(this, &QQuickPaintedItem::widthChanged, this, &QCustomChart::updateChartViewSize); connect(this, &QQuickPaintedItem::heightChanged, this, &QCustomChart::updateChartViewSize);}QCustomChart::~QCustomChart() { delete mCustomPlot; }void QCustomChart::paint(QPainter *painter) { /// add active check if (!painter->isActive()) return; QPixmap picture( boundingRect().size().toSize() ); QCPPainter qcpPainter( &picture ); mCustomPlot->toPainter(&qcpPainter); painter->drawPixmap(QPoint(), picture); }QCustomPlot *QCustomChart::getPlot() { return mCustomPlot; }void QCustomChart::mousePressEvent(QMouseEvent *event) { routeMouseEvents(event); }void QCustomChart::mouseReleaseEvent(QMouseEvent *event) { routeMouseEvents(event); }void QCustomChart::mouseMoveEvent(QMouseEvent *event) { routeMouseEvents(event); }void QCustomChart::mouseDoubleClickEvent(QMouseEvent *event) { routeMouseEvents(event); }void QCustomChart::wheelEvent(QWheelEvent *event) { routeWheelEvents( event ); }void QCustomChart::updateChartViewSize() { mCustomPlot->setGeometry(0, 0, (int)width(), (int)height()); mCustomPlot->setViewport(QRect(0, 0, (int)width(), (int)height())); }void QCustomChart::onChartViewReplot() { update(); }void QCustomChart::routeMouseEvents(QMouseEvent *event) { QMouseEvent* newEvent = new QMouseEvent(event->type(), event->localPos(), event->button(), event->buttons(), event->modifiers()); QCoreApplication::postEvent(mCustomPlot, newEvent); }void QCustomChart::routeWheelEvents(QWheelEvent *event) { QWheelEvent* newEvent = new QWheelEvent(event->pos(), event->delta(), event->buttons(), event->modifiers(), event->orientation()); QCoreApplication::postEvent(mCustomPlot, newEvent); } //qcustomline.h #include "qcustomchart.h"class QCustomLine : public QCustomChart { Q_OBJECT public: explicit QCustomLine(QQuickItem *parent = nullptr); virtual ~QCustomLine(); Q_INVOKABLE void initChart();Q_INVOKABLE void appendData(const double &key, const double &value); Q_INVOKABLE void replace(const QVector<double> &keys, const QVector<double> &values); Q_INVOKABLE void clearAll(); Q_INVOKABLE void setXYRange(int x_s, int x_e, int y_s, int y_e); virtual void timerEvent(QTimerEvent *event) override;Q_INVOKABLE void append_test(); Q_INVOKABLE void replace_test(); Q_INVOKABLE void updateUI();}; //qcustomline.cpp #include "qcustomline.h" #include "qcustomplot.h"QCustomLine::QCustomLine(QQuickItem *parent) : QCustomChart(parent) {}QCustomLine::~QCustomLine() {}void QCustomLine::initChart() { updateChartViewSize();getPlot()->addGraph(); getPlot()->graph(0)->setPen( QPen(Qt::red)); getPlot()->xAxis->setLabel( "t1" ); getPlot()->yAxis->setLabel( "S1" ); getPlot()->xAxis->setRange( 0, 1000 ); getPlot()->yAxis->setRange( 0, 10 ); getPlot()->setInteractions( QCP::iRangeDrag | QCP::iRangeZoom );startTimer(1000);connect(getPlot(), &QCustomPlot::afterReplot, this, &QCustomLine::onChartViewReplot);// getPlot()->replot(); }void QCustomLine::appendData(const double &key, const double &value) { getPlot()->graph(0)->addData(key, value); }void QCustomLine::replace(const QVector<double> &keys, const QVector<double> &values) { getPlot()->graph(0)->setData(keys, values); getPlot()->replot(); }void QCustomLine::clearAll() { getPlot()->graph(0)->setData(QVector<double>(), QVector<double>()); getPlot()->replot(); }void QCustomLine::setXYRange(int x_s, int x_e, int y_s, int y_e) { getPlot()->xAxis->setRange(x_s, x_e); getPlot()->yAxis->setRange(y_s, y_e); getPlot()->replot(); }void QCustomLine::timerEvent(QTimerEvent */*event*/) { static double t, U; U = ((double)rand() / RAND_MAX) * 5; getPlot()->graph(0)->addData(t++, U); getPlot()->replot(); }void QCustomLine::append_test() { static double t, U; U = ((double)rand() / RAND_MAX) * 5; appendData(t++, U); }void QCustomLine::replace_test() { QVector<double> tX; QVector<double> tY; tX << 1 << 3 << 4; tY << 1 << 5 << 1; replace(tX, tY); }void QCustomLine::updateUI() { getPlot()->replot(QCustomPlot::RefreshPriority::rpQueuedReplot); }

異常記錄:

1) 如下異常提示

?

如果出現這種異常提示:

QPainter::begin: Paint device returned engine = 0, type: 2

QPainter::setRenderHint: Painter must be active to set rendering hints

?

請檢查,

一:QML 是否已經用 ApplicationWindow 代替 Window 控件

二:在使用中,作者是通過 loader 加載的控件,并且在啟動之后默認調用了 replot() 根本原因在于時間差,paint device 并沒有準備好,所以可以略微延時執行,在構造函數中不要調用 replot()

?

2)在嵌入式等資源受限設備中出現,異常不知原因內存溢出死機情況

很有可能是由于過快過多的圖表刷新導致,內存資源耗盡導致程序嗝屁,建議跟新界面刷新策略,比如降低界面刷新的頻率,去掉沒有意義的界面刷新步驟

總結

以上是生活随笔為你收集整理的20200511-01 基于 QCustomPlot 移植到 QML 上(qt.514)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。