PyQt5踩坑

PyQt5 的文档相对较少,在自己的实际开发使用中,遇到了些许的坑。网上也没有大把的例子供我参考,还有好多例子停留在Qt4这个版本。所以记录于此,均为自己探索的较为良好的解决方案。包括:

  • 布局相关
  • 代码结构
  • qtpandas的版本问题
  • 切换主题
  • 数据库使用
  • pyqtgraph绘图
  • 提升窗口
  • Html的动态绘图

同样,代码太长,不能全部放上来,只放了核心代码,稍微有GUI开发基础的人都能看懂。

布局相关

还是使用 Qt designer 进行布局管理较为方便,写代码一行一行的调试实在是费劲。而且,可以在布局管理器中进行嵌套布局,如先对几个小控件进行水平布局,在对另外的空间垂直布局,最后整体网格布局,这样会较为便捷。效果如下所示:

verticalLayout_5 下面有多个布局。

代码结构

QWidget 是所有类的基类,也包括 QMainWindow ,而在设置窗口风格时,只能在 QWidget 里面使用 self.setStyleSheet(self.style) , 在 QMainWindow 里面则无效(这里的无效是指:切换主题后会有一些设置无法更改,导致界面很丑)。

但是,一个完整的窗口程序(包括任务栏,菜单栏,状态栏等)是离不开 QMainWindow 的,所以我们可以在 QMainWindow 设置中心区域为 QWidget ,然后在 QWidget 里面添加控件即可。

所以,我们需要两个 ui 文件。与控件相关的东西,如添加控件,修改控件可以在 QWidget 里面完成,而有关窗口的设置,如菜单栏,设置透明度,居中显示等可以在 QMainWindow 里面设置,最后将 QWidget 添加即可。

from mainwidget import Ui_Form #widget的ui
from mainwindow import Ui_MainWindow #mainwindow的ui

# 继承QWidget
class MyMainWidget(QWidget, Ui_Form):

    def __init__(self, parent = None):
        super(MyMainWidget, self).__init__(parent)
        self.setupUi(self)

        self.setLayout(self.gridLayout)

        # 退出窗口
        self.quit_btn.clicked.connect(self.quit_act)


    def quit_act(self):
        # sender 是发送信号的对象
        sender = self.sender()
        print(sender.text() + '键被按下')
        qApp = QApplication.instance()
        qApp.quit()

# 继承QMainWindow
class MyMainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self, parent = None):
        super(MyMainWindow, self).__init__(parent)
        self.setupUi(self)
        
        # 创建实例,并添加
        q = MyMainWidget()
        self.setCentralWidget(q)

        # 设置窗口透明
        self.setWindowOpacity(0.9)

        # self.resize(1000, 700)

        # 默认的状态栏
        # 可以设置其他按钮点击 参考多行文本显示 然而不行 
        self.status = self.statusBar()
        self.status.showMessage("你在主页面~")
        
        # 标题栏
        self.setWindowTitle("建模协会录入信息")

        # 窗口居中
        self.center()

    def center(self):
        '''
        获取桌面长宽
        获取窗口长宽
        移动
        '''
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2)

if __name__ == "__main__":
    # 在shell中执行
    app = QApplication(sys.argv)
    mywin = MyMainWindow()
    mywin.show()
    # 开始主循环,直到退出
    sys.exit(app.exec())

qtpandas的使用

pandas 是比较好好用的数据分析的库,而与 PyQt5 的结合,最方便的方法是使用 qtpandas 。这个库会将 pandas 的数据显示在 QTableWidget 上,自动实现 QTableWidget 的各种功能,如增加,排序,保存,删除等。

但是, qtpandas 暂时的版本只支持 PyQt4 ,如果想支持 PyQt5 ,需要去github下载最新版。下载好后进入目录,命令行内 python setup.py install 即可。

而且 qtpandas 依赖于 pandas 0.23 ,需要提前安装 pandas 0.23 。如果直接 pip install pandas 是不可以的,因为直接pip会到最新版0.25, qtpandas 不能使用,会直接报错:

No module named 'pandas.tslib

因此我创建了虚拟环境,直接 pip install pandas==0.23 即可,但是还不能放心使用。

通过这几天的使用发现, PyQt5 的依赖库做的都不是很好。

有些库 pip 后可以放心使用;

有些库 pip 后重启电脑才能生效,比如 pyqtgraph ;

有些库 pip 后还是用不了,比如 qtpandas

于是,我在github上下载了 qtpandas ,将文件夹放在代码的同级目录下,便可以引用进来,然后使用。期待开发者做后后面的完善吧。

https://github.com/draperjames/qtpandas

库的安装很费劲,但是,真的好用,代码与截图如下:

文件结构:(qtpandas的文件夹在这,调用里面的代码,库的本质还是代码啊)

执行效果:

代码如下:

from qtpandas.views.DataTableView import DataTableWidget
from qtpandas.models.DataFrameModel import DataFrameModel
class MyMainWidget(QWidget, Ui_Form):

    def __init__(self, parent = None):
        super(MyMainWidget, self).__init__(parent)
        self.setupUi(self)

        self.setLayout(self.gridLayout)

        # 退出窗口
        self.quit_btn.clicked.connect(self.quit_act)

        # qtpandas
        model = DataFrameModel() 
        # 空模型那个用于存储和处理数据
        # print(type(self.widget_2))
        self.widget_2.setViewModel(model)
        data = {
            'A': [10, 11, 12],
            'B': [12, 11, 10],
            'C': ['a', 'b', 'c']
        }
        self.df = pandas.DataFrame(data)
        self.df['A'] = self.df['A'].astype(np.int8) # 委托,规定某一列的类型
        model.setDataFrame(self.df)

        # 保存数据
        self.quit_btn_7.clicked.connect(self.save_data)

    def save_data(self):
        self.df.to_csv('data.csv')

    def quit_act(self):
        # sender 是发送信号的对象
        sender = self.sender()
        print(sender.text() + '键被按下')
        qApp = QApplication.instance()
        qApp.quit()

切换主题

对于我这种不会(不想写)前端的人来说,写 QSS(Qt Style Sheet) 无疑在要我命,不如用他人写好的代替一下,在代码中引入样式即可。这样也能实现界面和逻辑的代码分离。

别人写好的: https://blog.csdn.net/liang19890820/article/details/52384042

每个 Widget 都可以设置风格,因此建议主要界面使用 QWidget 作为窗口的主要区域用于设背景风格。

文件结构如下:

切换风格的代码如下:

# 样式的类
class StyleFile:
    def __init__(self):
        pass
    # @staticmethod
    def readQSS(style):
        with open (style, 'r') as f:
            return f.read()

# 在QWidget里面切换风格才有效
class MyMainWidget(QWidget, Ui_Form):

    def __init__(self, parent = None):
        super(MyMainWidget, self).__init__(parent)
        self.setupUi(self)
        self.quit_btn_3.clicked.connect(self.style_change)
        self.quit_btn_4.clicked.connect(self.style_change1)

    def style_change1(self):
        style_file = 'white.qss'
        self.style = StyleFile.readQSS(style_file)
        self.setStyleSheet(self.style)

    def style_change(self):
        style_file = 'black.qss'
        self.style = StyleFile.readQSS(style_file)
        self.setStyleSheet(self.style)

效果如下:

黑色主题

白色主题

而设置窗口的无边框风格、透明度风格则必须要在 QMainWindow 里面设置,因为这是窗口的特有方法。

数据库的使用

数据库的使用还是很常见的,对于开发小型的应用程序,使用 SQLite 即可(Manjaro环境下已经内置),以及可视化的管理软件SQLiteStudio。 PyQt 使用 QSqlDataBase 连接数据库,一个实例表示了一次连接(连接到IP地址,本地数据库均可),连接、操作完毕后记得关闭,否则会占用数据库的资源。

此外, QSqlTableModel 提供了可读写的数据模型,链接到数据库后可设置查询的表,设置过滤条件,执行查询语句。之后,将数据模型填充到 QTableView 中,可滚动,可编辑(编辑后改变数据库中的存储)。

放一次完整的代码吧,但是copy下来不能运行,因为没有 ui 文件,自己画一个或者只看数据库部分的代码吧。

#!/bin/bash
# -*- coding: UTF-8 -*-
import sys
import time
import PyQt5
# 基本控件都在这里面
from PyQt5.QtWidgets import (QApplication, QMainWindow, QDesktopWidget, QStyleFactory, QWidget,
                             QMessageBox, QTableView)
from PyQt5.QtGui import QPalette, QColor
from PyQt5.QtCore import Qt
# 导入数据库
from PyQt5.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel
from mainwidget import Ui_Form
from mainwindow import Ui_MainWindow

# 继承主窗口 Qmainwindow 和 自己画的界面 Ui_MainWindow
class MyMainWidget(QWidget, Ui_Form):

    def __init__(self, parent = None):
        super(MyMainWidget, self).__init__(parent)
        self.setupUi(self)

        self.setLayout(self.gridLayout)

        # 链接sql与查询
        self.db = QSqlDatabase.addDatabase("QSQLITE")
        self.db.setDatabaseName('table/test.db')
        self.db.open()
        if not self.db.open():
            QMessageBox.critical(None, ("无法打开数据库"), ("SQlite支持"), QMessageBox.Cancel)
            return False

        self.model = QSqlTableModel()

        self.pushButton.clicked.connect(self.insert)
        self.pushButton_2.clicked.connect(self.query)
        self.pushButton_3.clicked.connect(self.insert_oneline)
        self.pushButton_4.clicked.connect(self.del_oneline)
        self.pushButton_5.clicked.connect(self.find_row)

    # 打印行列号
    def find_row(self):
        print(self.view.currentIndex().row() + 1, self.view.currentIndex().column() + 1)

    # 删除一行
    def del_oneline(self):
        self.model.removeRow(self.view.currentIndex().row())
        self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
        self.model.select()
        self.view.setModel(self.model)
        self.view.show()       

    # 插入一行
    def insert_oneline(self):
        self.model.insertRows(self.model.rowCount(), 1)
        # print(str(ret))

    def query(self):
        self.model.setTable("people")
        self.model.setEditStrategy(QSqlTableModel.OnFieldChange)
        # self.model.setFilter("id > 1")
        self.model.select()
        self.model.setHeaderData(0, Qt.Horizontal, "ID")
        self.model.setHeaderData(1, Qt.Horizontal, "Name")
        self.model.setHeaderData(2, Qt.Horizontal, "Address")
        self.view.setModel(self.model)
        self.view.show()

    def insert(self):
        query = QSqlQuery()
        # query.exec_("create table people(id int primary key, name varchar(20), address varchar(30))")
        # query.exec_("insert into people values(1, 'one', 'test1')")
        # query.exec_("insert into people values(2, 'two', 'test2')")
        # query.exec_("insert into people values(3, 'three', 'test3')")
        # query.exec_("inse![](pyqt-pit/7.png)rt into people values(4, 'four', 'test4')")
        for i in range (6, 100):
            query.exec_("insert into people values({}, 'test', 'test{}')".format(i, i))

class MyMainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self, parent = None):
        super(MyMainWindow, self).__init__(parent)
        self.setupUi(self)

        self.q = MyMainWidget()
        self.setCentralWidget(self.q)

        # 设置窗口透明
        self.setWindowOpacity(0.9)

    # 关闭时,默认关闭数据库
    def closeEvent(self, e):
        self.q.db.close()


if __name__ == "__main__":
    # 在shell中执行
    app = QApplication(sys.argv)
    mywin = MyMainWindow()
    mywin.show()
    # 开始主循环,直到退出
    sys.exit(app.exec())

pyqtgraph使用

这个库,简直有毒,总以为我装失败了,没想到关机开机后这个库能用了。

这个绘图库是纯 python 图形 GUI 库,由于是基于 pyqt 开发的集成绘图模块,所以 PyQtGraph 绘图与底层方式实现绘图功能在速度上的区别不大。这个库的好处是,可以写两行代码,点击 run example 查看所有的绘图效果。

import pyqtgraph.examples
pyqtgraph.examples.run()

绘图效果,看下图,个人感觉还可以,虽然比不上 matlab 的工具箱和 matplotlib

模仿上述的例子进行简单的集成。这里用到了提升窗口的技术,如果不了解,可以先看后文的提升窗口。基类: QWidget ,头文件: pyqtgraph , 名称: GraphicsLayoutWidget ,一个字母都不要错哦。在本代码中,对象的名称为: pyqtgraph2pyqtgraph

import pyqtgraph as pg 
class MyMainWidget(QWidget, Ui_Form):

    def __init__(self, parent = None):

        super(MyMainWidget, self).__init__(parent)
        # 在初始化之前设置pg,因为初始化会写死配置,无法在更改
        pg.setConfigOption('background', '#f0f0f0')
        pg.setConfigOption('foreground', 'd')
        # 使曲线看起来光滑
        pg.setConfigOptions(antialias = True)

        self.setupUi(self)
        self.setLayout(self.gridLayout)

        # 退出窗口
        self.quit_btn.clicked.connect(self.quit_act)

        # 绘图
        self.pushButton.clicked.connect(self.graph_plot)
        self.pushButton_2.clicked.connect(self.graph_plot1)

    # 多曲线绘图
    def graph_plot1(self):
        self.pyqtgraph2.clear()
        plt = self.pyqtgraph2.addPlot(title="test")
        x = np.random.normal(size=20)
        y1 = np.sin(x)
        y2 = 1.1 * np.sin(x + 1)
        bg1 = pg.BarGraphItem(x = x, height = y1, width = 2, brush = 'r')
        bg2 = pg.BarGraphItem(x = x, height = y2, width = 2, brush = 'b')
        plt.addItem(bg1)
        plt.addItem(bg2)
        # 新的一列还是新的一行
        # self.pyqtgraph2.nextColumn()
        self.pyqtgraph2.nextRow()
        plt2 = self.pyqtgraph2.addPlot(title="test1")
        x = np.linspace(1, 20, 20)
        y3 = np.random.normal(size=20)
        plt2.plot(x, y3, pen = pg.mkPen(width = 2, color = 'd'))
        plt2.showGrid(x=True, y=True)

    # 单标题,多曲线绘图
    def graph_plot(self):
        self.pyqtgraph.clear()
        # 两种绘图方式
        # self.pyqtgraph.addPlot(y = np.random.normal(size=100),
            # pen = pg.mkPen(color='b', width=2))
        plt2 = self.pyqtgraph.addPlot(title="multi rules")
        plt2.plot(np.random.normal(size=150),
            pen = pg.mkPen(color='r', width=2))
        plt2.plot(np.random.normal(size=150) + 5,
            pen = pg.mkPen(color='b', width=2))

Matplotlib与PyQt的结合

谈到绘图,不得不提一下 Matplotlib ,很出名的python绘图库。如果可以把 Matplotlib 绘制的图形嵌入到 PyQt 中,也就避免了底层绘制图像的繁琐。

说干就干。(官网也有实例)

工具库的引入:

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5 import NavigationToolbar2QT as NavigationToolbar

创建空白的绘图界面的类,实现静态绘图和动态绘图两种方法

# 绘图的空白界面
class MymplCanvas(FigureCanvas):

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = self.fig.add_subplot(111) # 多界面绘图
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(self, 
            QSizePolicy.Expanding, QSizePolicy.Expanding
        )
        FigureCanvas.updateGeometry(self)

    def static_plot(self):
        self.axes.clear()
        self.fig.suptitle("static FIG")
        t = np.linspace(1, 10, 10)
        s = np.sin(np.pi * t)
        self.axes.plot(t, s)
        self.axes.grid(True)
        self.draw()

    # 为何要加参数
    def dynamic_plot(self, *args, **kwargs):
        timer = QTimer(self)
        timer.timeout.connect(self.update_fig)
        timer.start(1000)

    def update_fig(self):
        self.axes.clear()
        self.fig.suptitle("dynamic FIG")
        l = np.random.randint(1, 10, 4)
        self.axes.plot([0, 1, 2, 3], l, 'r')
        self.axes.grid(True)
        self.draw()

之后,封装绘图类。将绘图类封装到 MatplotlibWidget ,调用 MatplotlibWidget 直接实现绘图功能。

# 实现绘图类
class MatplotlibWidget(QWidget):
    def __init__(self, parent=None):
        super(MatplotlibWidget, self).__init__(parent)

        # 封装绘图类
        self.gridLayout = QGridLayout()
        self.mpl = MymplCanvas(self)
        # 添加工具栏
        self.mpl_tool = NavigationToolbar(self.mpl, self)
        self.setLayout(self.gridLayout)
        self.gridLayout.addWidget(self.mpl)
        self.gridLayout.addWidget(self.mpl_tool)

    def static(self):
        self.mpl.static_plot()

    def dynamic(self):
        self.mpl.dynamic_plot()

之后在窗口 QWidget 里面调用 MatplotlibWidget 即可。

class MyMainWidget(QWidget, Ui_Form):

    def __init__(self, parent = None):
        super(MyMainWidget, self).__init__(parent)
        self.setupUi(self)

        self.setLayout(self.gridLayout)

        # 退出窗口
        self.quit_btn.clicked.connect(self.quit_act)

        # 提升后
        self.widget = MatplotlibWidget()
        self.widget.setVisible(False)
        self.widget_2 = MatplotlibWidget()
        self.widget_2.setVisible(False)
        self.gridLayout.addWidget(self.widget)
        self.gridLayout.addWidget(self.widget_2)
        self.pushButton.clicked.connect(self.dynamic)
        self.pushButton_2.clicked.connect(self.static)

    def static(self):
        self.widget.setVisible(True)
        self.widget.mpl.static_plot()

    def dynamic(self):
        self.widget_2.setVisible(True)
        self.widget_2.mpl.dynamic_plot()

效果如下所示:

提升窗口

已经含有的类

在上文已经提到了一次提升窗口。再说这个之前,确保已经看懂了上面 pyqtgraphmatplotlib 的例子,不然这里更加看不懂。之后会在说明自定义和引用已有类的角度说明如何提升窗口。(毕竟我之前也以为这个没多大用)

基类: QWidget ,头文件: pyqtgraph , 名称: GraphicsLayoutWidget

因为pyqtgraph是已经安装好的库,所以可以设置头文件为 pyqtgraph ,相当与传统的 import

而在Qt Designer内,首先将 Widget 托入界面,右键,提升为。(不好意思这里没办法截图,linux下的截图可真难用,wine QQ的截图也不能全局有效)

输入:头文件: pyqtgraph , 名称: GraphicsLayoutWidget 。(不要输入错误,一个字母都不要错)

输入后以此点击添加、提升即可。

之后 pyuic5 -o mainwidget.py mainwidget.ui 后,会在辅助的py文件里发现: from pyqtgraph import GraphicsLayoutWidget 这么一句话,也就是,上面说的传统的import。

相当与在库 pyqtgraph 中引入了一个布局,并且给了这个布局一个界面,这个界面可以实现绘图功能,那么以后在想绘图的时候就可以复制、拖动这个界面,更加轻松的布局和设置大小。此时提升完毕。

以上是在有相应的库和方法的前提下设置提升类。如果没有相应的库,如上文的 MatplotlibWidget ,如何将自己写的类关联到 Widget 里面进行提升,形成容易操作的控件呢?且看下文。

自己写的类

这个时候需要将自己写的类单独拿出来成为一个文件,在同级目录下引用即可。

文件结构:

提升方法

自行托入 Widget ,右键提升,输入名称和头文件,名称是类名,文件就是同级目录下的文件,最后添加,提升即可。

相关代码:

MatplotlibWidget.py

#!/bin/bash
# -*- coding: UTF-8 -*-
import sys
import numpy as np
import PyQt5
# 基本控件都在这里面
from PyQt5.QtWidgets import (QApplication, QMainWindow, QDesktopWidget, QStyleFactory, QWidget,
                                QSizePolicy, QPushButton, QGridLayout)
from PyQt5.QtGui import QPalette, QColor
from PyQt5.QtCore import Qt, QTimer
from mainwidget import Ui_Form
from mainwindow import Ui_MainWindow

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5 import NavigationToolbar2QT as NavigationToolbar
# 绘图的空白界面
class MymplCanvas(FigureCanvas):

    def __init__(self, parent=None, width=5, height=4, dpi=100):
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = self.fig.add_subplot(111) # 多界面绘图
        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(self, 
            QSizePolicy.Expanding, QSizePolicy.Expanding
        )
        FigureCanvas.updateGeometry(self)

    def static_plot(self):
        self.axes.clear()
        self.fig.suptitle("static FIG")
        t = np.linspace(1, 10, 10)
        s = np.sin(np.pi * t)
        self.axes.plot(t, s)
        self.axes.grid(True)
        self.draw()

    # 为何要加参数
    def dynamic_plot(self, *args, **kwargs):
        timer = QTimer(self)
        timer.timeout.connect(self.update_fig)
        timer.start(1000)

    def update_fig(self):
        self.axes.clear()
        self.fig.suptitle("dynamic FIG")
        l = np.random.randint(1, 10, 4)
        self.axes.plot([0, 1, 2, 3], l, 'r')
        self.axes.grid(True)
        self.draw()

# 实现绘图类
class MatplotlibWidget(QWidget):
    def __init__(self, parent=None):
        super(MatplotlibWidget, self).__init__(parent)

        # 封装绘图类
        self.gridLayout = QGridLayout()
        self.mpl = MymplCanvas(self)
        self.mpl_tool = NavigationToolbar(self.mpl, self)
        self.setLayout(self.gridLayout)
        self.gridLayout.addWidget(self.mpl)
        self.gridLayout.addWidget(self.mpl_tool)

    def static(self):
        self.mpl.static_plot()

    def dynamic(self):
        self.mpl.dynamic_plot()

引用

最终呈现的效果和上面matplotlib绘图一样。这里只给出对比部分的代码。

class MyMainWidget(QWidget, Ui_Form):

    def __init__(self, parent = None):
        super(MyMainWidget, self).__init__(parent)
        self.setupUi(self)

        self.setLayout(self.gridLayout)
        # 提升前
        # self.widget = MatplotlibWidget()
        # self.widget.setVisible(False)
        # self.widget_2 = MatplotlibWidget()
        # self.widget_2.setVisible(False)
        # print(type(self.widget_2))

        # 提升后 不用创建实例,直接拖一拖,pyuic5一下即可
        self.gridLayout.addWidget(self.widget)
        self.gridLayout.addWidget(self.widget_2)
        self.pushButton.clicked.connect(self.dynamic)
        self.pushButton_2.clicked.connect(self.static)

Html的动态绘图

直接引入画好的图片即可,不过图片的后缀是html,使用 QWebEngineView 加载即可,一个坑是:必须使用绝对路径,相对路径是找不到的。另一个坑是,Qt4 Designer里面没有 QWebEngineView 这个类,因为这个类是新的,Qt4 Designer 里面只有旧的类 QWebView 。别问我为什么不用新的,因为linux下还没有Qt5 designer。

旧的类不再维护,新的类使用chromium内核,如果不想写代码实现(布局,定位,大小,这里写代码很麻烦的),那么怎么在Qt4 Designer使用新的类呢?

很简单,使用上文说的提升窗口,设置好基类,头文件,名称就很容易在旧界面中使用新的类了。

提升窗口为 QWebEngineView , 同样不要写错一个字母。

Html的绘图技术的强大之处在于炫酷、可交互。而python也不缺少html的绘图库,如 plotly (javascript的绘图库,python调用接口),还有pyecharts,也很炫酷。(pyecharts版本做了更新,之前就版本的代码无法运行,我一年前的时候还用的旧版本,新版本的用法参考github)

echarts的(我写的时候服务器维修,无法下载图片,使用的pyecharts的):

https://gallery.echartsjs.com/explore.html#sort=rank~timeframe=all~author=all

pyecahrts的: https://github.com/pyecharts/pyecharts/tree/master/example

我随意挑选了一个,执行后生成本地的html文件(可交互的图形)。

文件结构:

效果如下所示:

代码如下:

# 继承主窗口 Qmainwindow 和 自己画的界面 Ui_MainWindow
class MyMainWidget(QWidget, Ui_Form):

    def __init__(self, parent = None):
        super(MyMainWidget, self).__init__(parent)
        self.setupUi(self)

        self.setLayout(self.gridLayout)

        # html 绘图
        self.quit_btn_2.clicked.connect(self.html_plot)

    def html_plot(self):
        # 必须用绝对路径
        url = "/home/lanling/Srcode/python/tools/GUI/practice/Pyecharts/render.html"
        # web_view 是 QWebEngineView 对象的一个实例
        self.web_view.load(QUrl.fromLocalFile(url))

结束语

因为这里给的都是核心代码,没有给全部代码,如果你是在弄不出来,底下留言给下邮箱,我给你代码。

不过还是建议多折腾,多走两步,多研究,伸手党不好。

下一步,自定义信号与槽,类与函数进阶,多线程。

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章