本文涉及:Windows操作系统,PyChrm,PyQt5,Qt Designer,pyecharts
目录
二、实战示例:在frame控件中显示pyecharts生成的图表
一、前言
前段时间有个想法,就是把pyecharts图表在Qt的控件中显示出来,毕竟它的颜值是有目共睹的。用过的小伙伴应该知道,通过pyecharts作图,我们可以通过render()函数生成一份后缀名为html的文件到本地,而文件的图标是一个浏览器样式。
这个html文件其实就可以称之为本地web,因为当你双击打开它时,它是通过浏览器打开的,而且网址也和通常www开头的不一样。
除此之外,我们还可以通过Qt来显示网页内容,比如百度首页,这个就是外部web。具体如何实现,下面我将分为两大块来讲。
二、实战示例:在frame控件中显示pyecharts生成的图表
如果要在控件中加载并显示网页,单单靠信号槽是无法实现的,我们还需要用到Qt中的QWebEngineView。这是一个基于Chrome浏览器内核引擎的高级控件,它所提供的功能和方法还是比较强大的。
注:V5.11及更高版本的PyQt5中不包含QWebEngineView,请另外单独下载:
pip install PyQtWebEngine
如果你和我一样,用的也是PyCharm,那你也可以在Python解释器中直接下载安装,具体步骤如下图所示:
安装完成之后,我们先用pyecharts生成一个简单的折线图的html文件到本地,代码如下:
# 导入pyecharts中折线图
from pyecharts.charts import Line
# 简单写2个列表:一个是x轴数据,一个是y轴数据
list_x = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
list_y = [22, 54, 73, 86, 121, 115, 96, 103, 78, 83, 62, 35]
# 绘制1个最基础的折线图
line = (
Line()
.add_xaxis(xaxis_data = list_x)
.add_yaxis(y_axis = list_y, series_name = '基础折线图')
)
# 生成html文件到本地文件夹,取名为test
line.render(r'C:\Users\Administrator\Desktop\示例代码\test.html')
第2步,我们在Qt Designer中简单设计一下UI界面,并在其中放置一个frame控件。如下图所示(因为没有给frame设置背景色,所以看起来好像什么也没放,小伙伴们只要看图片中右侧的对象查看器中有哪些内容就行了):
界面设计好之后,我们保存一下:
后缀名是.ui的就是我们刚刚做好的UI界面文件了。接下来,我们打开PyCharm,用具体代码来实现我们想要的结果。
这里我是用了UI与逻辑代码分离去做的,如果你还不了解,请点击超链接移步我的另一篇文章。具体代码如下(温馨提示:核心代码在2条虚线之间):
from PyQt5 import QtWidgets, QtWebEngineWidgets
from PyQt5.QtCore import QUrl
from untitled import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
# --------------- start ---------------------
self.webEngineView = QtWebEngineWidgets.QWebEngineView(self.frame)
url = r'file:///C:/Users/Administrator/Desktop/%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81/test.html'
self.webEngineView.load(QUrl(url))
print(self.frame.width(), self.frame.height())
self.webEngineView.setGeometry(0, 0, 1063, 682)
# --------------- end -----------------------
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
代码运行后,效果如下图所示:
从图片中我们发现,虽然图表是正常显示出来了,但是位置有些偏左上角了,而且由于UI窗体较大,导致图表上的字符显得过小,有些看不清,这时我们就需要再加一句代码调整一下就行了,具体代码如下:
# --------------- start ---------------------
self.webEngineView = QtWebEngineWidgets.QWebEngineView(self.frame)
url = r'file:///C:/Users/Administrator/Desktop/%E7%A4%BA%E4%BE%8B%E4%BB%A3%E7%A0%81/test.html'
self.webEngineView.load(QUrl(url))
self.webEngineView.setGeometry(0, 0, 1063, 682)
# 这里是添加的代码 ↓
self.webEngineView.setZoomFactor(1.2)
# --------------- end -----------------------
这里我们是用到了setZoomFactor函数,这个函数的意思就是说此属性保存页面内容的缩放因子。有效值在0.25到5.0之间。默认系数为1.0。再次运行代码,效果如下图所示:
这样看起来,是不是就舒服多了?但是实际上,其中还存在一个很大的问题,那就是不能和控件一起自适应窗口。细心的小伙伴可能会发现,我在Qt Designer中设计UI界面的时候,是在窗体中加了一个水平布局的,但是当我点击窗口最大化时,图表界面并没有自适应,如下图所示:
很遗憾,这个问题困扰了我很久,并且到目前为止我自己也还没有解决……如果有博学多才的小伙伴能帮我解决这个问题,非常欢迎在评论区留言告诉我,角角感激不尽!
那么显示本地web页面至此搁笔,下面我再讲一下如何显示外部web页面。
三、实战示例:在frame控件中显示百度首页
显示外部web和本地web的实现原理基本是一致的,只不过把本地的html文件的网址换成了百度首页的地址。我们先对比看一下这2个网址的区别:
虽然原理是一致的,但是这2个网址还是有很大差别的。本地web页面的网址和我们电脑上的文件路径非常相似,尾部带了文件的后缀名.html。和文件路径区别最大的是,它头部多了个file:///。
我之前写代码的时候,出现报错就是因为地址没有写全。小伙伴在复制本地web地址的时候,记得双击网址栏,这样才会看到完整的地址哦~
和显示本地web页面的方法基本一致,这里我们仍需用到QWebEngineView。它的常用方法如下:
方法 | 描述 |
load(QUrl url) | 加载指定的URL并显示 |
setHtml(QString & html) | 将网页视图的内容设置为指定的HTML内容 |
QWebEngineView控件使用load()函数加载一个web页面,实际上就是使用HTTP GET方法加载web页面,它既可以加载本地的web页面,也可以加载远程的外部web页面。
以百度首页为例,具体代码如下(核心代码在2条虚线之间):
from PyQt5 import QtWidgets, QtWebEngineWidgets
from PyQt5.QtCore import QUrl
from untitled import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
# --------------- start ---------------------
self.webEngineView = QtWebEngineWidgets.QWebEngineView(self.frame)
url = 'https://www.baidu.com/'
self.webEngineView.load(QUrl(url))
self.webEngineView.setGeometry(0, 0, 1063, 682)
# --------------- end -----------------------
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())
运行后效果图如下:
感谢小伙伴能在茫茫文海中点开我的拙作,如果对你有用,期待你的关注和点赞,也非常欢迎小伙伴们在评论区留言,角角一定知无不言言无不尽。