文章目錄
- 1 批量替換代替追加
- 1.1 測試1
- 1.2 測試2
- 1.3 測試3
- 2 開啟OpenGL
- 2.1 測試1
- 2.2 測試2
- 2.3 測試3
- 2.4 測試4
更多精彩內容 |
---|
👉內容導航 👈 |
👉Qt開發 👈 |
👉QtCharts繪圖 👈 |
👉python開發 👈 |
1 批量替換代替追加
環境 | 說明 |
---|---|
系統 | windows10 |
python | 3.13 |
pyside6 | 6.8.3 |
性能分析工具 | line_profiler_pycharm |
-
如下所示,使用
replace
添加數據和使用append
添加數據性能對比,單次添加數據越多,replace性能比append越強。 -
示例代碼
import random # 導入random模塊,用于生成隨機數 import sysfrom PySide6.QtCharts import QChart, QChartView, QLineSeries, QValueAxis # 導入QtCharts模塊,用于創建圖表和軸 from PySide6.QtCore import QTimer # 導入QTimer,用于定時更新圖表 from PySide6.QtCore import Qt # 導入Qt核心模塊,用于設置對齊方式等 from PySide6.QtGui import QPainter # 導入QPainter,用于設置圖表的渲染提示 from PySide6.QtWidgets import QApplication, QMainWindow # 導入PySide6的QApplication和QMainWindow類 from line_profiler_pycharm import profile from PySide6.QtCore import QPointFclass MainWindow(QMainWindow): # 定義MainWindow類,繼承自QMainWindowdef __init__(self):super().__init__() # 調用父類的構造函數self.setWindowTitle("PySide6 折線圖示例") # 設置窗口標題self.setGeometry(100, 100, 800, 600) # 設置窗口的位置和大小self.timer = QTimer() # 創建一個定時器self.timer.timeout.connect(self.update_chart) # 連接定時器超時信號到update_chart方法self.timer.start(10) # 設置定時器間隔為10毫秒,并啟動定時器# print(help(QChart)) # 這行代碼可以用于打印QChart類的幫助信息,目前被注釋掉了self.chart_view = None # 初始化圖表視圖為Noneself.series1 = QLineSeries() # 創建一個折線序列對象self.series2 = QLineSeries() # 創建一個折線序列對象# self.series1.setUseOpenGL(True) # 設置折線序列使用OpenGL渲染# self.series2.setUseOpenGL(True) # 設置折線序列使用OpenGL渲染self.init_chart() # 調用初始化圖表的方法def init_chart(self): # 定義初始化圖表的方法# 設置名稱self.series1.setName("series1") # 設置折線的名稱self.series2.setName("series2") # 設置折線的名稱# 創建圖表chart = QChart() # 創建一個圖表對象chart.addSeries(self.series1) # 將折線序列添加到圖表中chart.addSeries(self.series2) # 將折線序列添加到圖表中chart.setTitle("簡單的折線圖") # 設置圖表的標題# chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations) # 設置圖表不使用動畫# 創建x軸和y軸axis_x = QValueAxis() # 創建一個數值型x軸axis_y = QValueAxis() # 創建一個數值型y軸chart.addAxis(axis_x, Qt.AlignmentFlag.AlignBottom) # 將x軸添加到圖表底部chart.addAxis(axis_y, Qt.AlignmentFlag.AlignLeft) # 將y軸添加到圖表左側self.series1.attachAxis(axis_x) # 將折線序列附著到x軸self.series1.attachAxis(axis_y) # 將折線序列附著到y軸self.series2.attachAxis(axis_x) # 將折線序列附著到x軸self.series2.attachAxis(axis_y) # 將折線序列附著到y軸# 創建圖表視圖self.chart_view = QChartView(chart) # 創建一個圖表視圖對象,并將圖表添加進去self.chart_view.setRenderHint(QPainter.RenderHint.Antialiasing) # 設置圖表視圖的渲染提示為抗鋸齒# 設置主窗口的中心部件self.setCentralWidget(self.chart_view) # 設置主窗口的中心部件為圖表視圖@profiledef update_chart1(self): # 定義更新圖表的方法"""使用append方法更新折線序列:return: """for i in range(10): # 循環10次random_integer = random.randint(1, 100) # 生成一個1到100之間的隨機整數self.series1.append(self.series1.count(), random_integer) # 將新的點添加到折線序列中chart = self.chart_view.chart() # 獲取圖表視圖中的圖表對象axis_x = chart.axes(Qt.Orientation.Horizontal)[0] # 獲取圖表中的x軸對象axis_y = chart.axes(Qt.Orientation.Vertical)[0] # 獲取圖表中的y軸對象axis_x.setRange(0, self.series1.count()) # 設置x軸的范圍,使其從0到當前折線序列點的數量axis_y.setRange(0, 100) # 設置y軸的范圍,使其從0到100@profiledef update_chart2(self): """使用replace方法更新折線序列:return: """data = self.series2.points()for i in range(10): # 循環10次random_integer = random.randint(1, 100) # 生成一個1到100之間的隨機整數data.append(QPointF(len(data), random_integer)) # 將新的點添加到折線序列中self.series2.replace(data) # 替換折線序列中的點chart = self.chart_view.chart() # 獲取圖表視圖中的圖表對象axis_x = chart.axes(Qt.Orientation.Horizontal)[0] # 獲取圖表中的x軸對象axis_y = chart.axes(Qt.Orientation.Vertical)[0] # 獲取圖表中的y軸對象axis_x.setRange(0, self.series2.count()) # 設置x軸的范圍,使其從0到當前折線序列點的數量axis_y.setRange(0, 100) # 設置y軸的范圍,使其從0到100@profiledef update_chart(self): # 定義更新圖表的方法self.update_chart1() # 調用更新圖表的方法self.update_chart2() # 調用更新圖表的方法if __name__ == "__main__": # 確保只有在直接運行此腳本時才會執行下面的代碼app = QApplication(sys.argv) # 創建一個QApplication對象window = MainWindow() # 創建一個MainWindow對象window.show() # 顯示主窗口sys.exit(app.exec()) # 進入應用程序的主循環,并等待退出
1.1 測試1
- 測試方法:定時器1秒刷新1次,每次在循環中添加10個點數據;
- 測試結果:
- 從整個函數看
update_chart1
耗時是update_chart2
的6.5倍; - 從單行代碼看
append
耗時是replace
的11.3倍;
- 從整個函數看
1.2 測試2
- 測試方法:定時器1秒刷新1次,每次在循環中添加1000個點數據;
- 測試結果:
- 從整個函數看
update_chart1
耗時是update_chart2
的199倍; - 從單行代碼看
append
耗時是replace
的750倍;
- 從整個函數看
1.3 測試3
- 測試方法:定時器10毫秒刷新1次,每次在循環中添加10個點數據;
- 測試結果:
- 從整個函數看
update_chart1
耗時是update_chart2
的5.57倍; - 從單行代碼看
append
耗時是replace
的8.82倍;
- 從整個函數看
2 開啟OpenGL
環境 | 說明 |
---|---|
系統 | windows10 |
python | 3.13 |
pyside6 | 6.8.3 |
性能分析工具 | line_profiler_pycharm |
-
如下所示,對比開啟OpenGL和開啟OpenGL的性能區別;當使用appeng添加數據時,開啟opengl和不開opengl的區別最大;
-
示例代碼:
import random # 導入random模塊,用于生成隨機數 import sysfrom PySide6.QtCharts import QChart, QChartView, QLineSeries, QValueAxis # 導入QtCharts模塊,用于創建圖表和軸 from PySide6.QtCore import QTimer # 導入QTimer,用于定時更新圖表 from PySide6.QtCore import Qt # 導入Qt核心模塊,用于設置對齊方式等 from PySide6.QtGui import QPainter # 導入QPainter,用于設置圖表的渲染提示 from PySide6.QtWidgets import QApplication, QMainWindow # 導入PySide6的QApplication和QMainWindow類 from line_profiler_pycharm import profile from PySide6.QtCore import QPointFclass MainWindow(QMainWindow): # 定義MainWindow類,繼承自QMainWindowdef __init__(self):super().__init__() # 調用父類的構造函數self.setWindowTitle("PySide6 折線圖示例") # 設置窗口標題self.setGeometry(100, 100, 800, 600) # 設置窗口的位置和大小self.timer = QTimer() # 創建一個定時器self.timer.timeout.connect(self.update_chart) # 連接定時器超時信號到update_chart方法self.timer.start(1000) # 設置定時器間隔為10毫秒,并啟動定時器self.chart_view = None # 初始化圖表視圖為Noneself.series1 = QLineSeries() # 創建一個折線序列對象self.series2 = QLineSeries() # 創建一個折線序列對象self.series1.setUseOpenGL(True) # 設置折線序列使用OpenGL渲染# self.series2.setUseOpenGL(True) # 設置折線序列使用OpenGL渲染self.init_chart() # 調用初始化圖表的方法def init_chart(self): # 定義初始化圖表的方法# 設置名稱self.series1.setName("series1") # 設置折線的名稱self.series2.setName("series2") # 設置折線的名稱# 創建圖表chart = QChart() # 創建一個圖表對象chart.addSeries(self.series1) # 將折線序列添加到圖表中chart.addSeries(self.series2) # 將折線序列添加到圖表中chart.setTitle("簡單的折線圖") # 設置圖表的標題# chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations) # 設置圖表不使用動畫# 創建x軸和y軸axis_x = QValueAxis() # 創建一個數值型x軸axis_y = QValueAxis() # 創建一個數值型y軸axis_y.setRange(0, 100) # 設置y軸的范圍,使其從0到100chart.addAxis(axis_x, Qt.AlignmentFlag.AlignBottom) # 將x軸添加到圖表底部chart.addAxis(axis_y, Qt.AlignmentFlag.AlignLeft) # 將y軸添加到圖表左側self.series1.attachAxis(axis_x) # 將折線序列附著到x軸self.series1.attachAxis(axis_y) # 將折線序列附著到y軸self.series2.attachAxis(axis_x) # 將折線序列附著到x軸self.series2.attachAxis(axis_y) # 將折線序列附著到y軸# 創建圖表視圖self.chart_view = QChartView(chart) # 創建一個圖表視圖對象,并將圖表添加進去self.chart_view.setRenderHint(QPainter.RenderHint.Antialiasing) # 設置圖表視圖的渲染提示為抗鋸齒# 設置主窗口的中心部件self.setCentralWidget(self.chart_view) # 設置主窗口的中心部件為圖表視圖@profiledef update_chart1(self): # 定義更新圖表的方法"""開啟OpenGL渲染,使用append方法更新折線序列:return:"""for i in range(10): # 循環10次random_integer = random.randint(1, 100) # 生成一個1到100之間的隨機整數self.series1.append(self.series1.count(), random_integer) # 將新的點添加到折線序列中@profiledef update_chart2(self):"""不開啟OpenGL渲染,使用append方法更新折線序列:return:"""for i in range(10): # 循環10次random_integer = random.randint(1, 100) # 生成一個1到100之間的隨機整數self.series2.append(self.series2.count(), random_integer) # 將新的點添加到折線序列中@profiledef update_chart(self): # 定義更新圖表的方法self.update_chart1() # 調用更新圖表的方法self.update_chart2() # 調用更新圖表的方法chart = self.chart_view.chart() # 獲取圖表視圖中的圖表對象axis_x = chart.axes(Qt.Orientation.Horizontal)[0] # 獲取圖表中的x軸對象max_x = self.series2.count()axis_x.setRange(0, max_x) # 設置x軸的范圍,使其從0到當前折線序列點的數量if __name__ == "__main__": # 確保只有在直接運行此腳本時才會執行下面的代碼app = QApplication(sys.argv) # 創建一個QApplication對象window = MainWindow() # 創建一個MainWindow對象window.show() # 顯示主窗口sys.exit(app.exec()) # 進入應用程序的主循環,并等待退出
2.1 測試1
- 測試方法:定時器1秒刷新1次,每次在循環中添加10個點數據;
- 測試結果:
- 從整個函數看
update_chart2
耗時是update_chart1
的9.7倍; - 從單行代碼看
append
添加數據不開啟opengl耗時是開啟opengl的21.3倍;
- 從整個函數看
2.2 測試2
- 測試方法:定時器1秒刷新1次,每次在循環中添加1000個點數據;
- 測試結果:
- 從整個函數看
update_chart2
耗時是update_chart1
的123倍; - 從單行代碼看
append
添加數據不開啟opengl耗時是開啟opengl的169倍;
- 從整個函數看
2.3 測試3
- 測試方法:定時器10毫秒刷新1次,每次在循環中添加10個點數據;
- 測試結果:
- 從整個函數看
update_chart2
耗時是update_chart1
的72.5倍; - 從單行代碼看
append
添加數據不開啟opengl耗時是開啟opengl的113倍;
- 從整個函數看
2.4 測試4
-
測試方法:將使用append添加數據改為使用replace添加數據,定時器10毫秒刷新1次,每次在循環中添加10個點數據;
-
測試結果:
- 從整個函數看
update_chart2
耗時是update_chart1
的1.84倍; - 從單行代碼看
replace
添加數據不開啟opengl耗時是開啟opengl的11倍;
- 從整個函數看
-
測試代碼:
@profiledef update_chart1(self): # 定義更新圖表的方法"""開啟OpenGL渲染,使用append方法更新折線序列:return:"""data = self.series1.points()for i in range(10): # 循環10次random_integer = random.randint(1, 100) # 生成一個1到100之間的隨機整數data.append(QPointF(len(data), random_integer)) # 將新的點添加到折線序列中self.series1.replace(data) # 替換折線序列中的點@profiledef update_chart2(self):"""不開啟OpenGL渲染,使用append方法更新折線序列:return:"""data = self.series2.points()for i in range(10): # 循環10次random_integer = random.randint(1, 100) # 生成一個1到100之間的隨機整數data.append(QPointF(len(data), random_integer)) # 將新的點添加到折線序列中self.series2.replace(data) # 替換折線序列中的點