PYQT/QT 开发VUE ELEMENT应用程序(完结)
PYQT/QT 开发VUE ELEMENT应用程序(完结)基础参考前篇文章PYQT/QT 开发VUE GUI应用程序框架完结,基于vue-element-admin开发因为本人在对前端不是很熟悉, 只会做日常开发 可能很多地方表述不准请见谅实际上开发起来还是比较割裂的,而且运行起来的顺滑度也没浏览器快的感觉,交互性能暂时没有测试修改后的前端项目 已经上传到gitee1. 测试效果2. ELEMEN
PYQT/QT 开发VUE ELEMENT应用程序(完结)
基础参考前篇文章
框架完结,基于vue-element-admin开发
因为本人在对前端不是很熟悉, 只会做日常开发 可能很多地方表述不准请见谅
实际上开发起来还是比较割裂的,而且运行起来的顺滑度也没浏览器快的感觉,交互性能暂时没有测试
修改后的前端项目 已经上传到gitee
1. 测试效果
2. ELEMENT端修改
在vue-admin-template中clone代码, 根据markdown中文文档步骤构建环境并启动
启动完成后进行修改添加功能
以table页面作为改动参考 改动结构如下
所做的更改 只有加入了两个js,修改了main.js 修改table.vue进行交互
2.1 加入两个必要的js
qt-request.js
import Vue from 'vue' // 引入Vue在初始化qtWebChannel后将object放入全局
import { QWebChannel } from './qwebchannel'
import { Message } from 'element-ui'
if (process.env.NODE_ENV === 'development') {
window.qt = {
webChannelTransport: {
send() {
console.log(`
QWebChannel simulator activated !
启动QT桌面端后请注销此段代码
`)
}
}
}
}
export var callBackDict = {}
export var qtWebChannel = null // 导出qtWebChannel,供其他页面调用
new QWebChannel(qt.webChannelTransport, (channel) => {
// all published objects are available in channel.objects under
// the identifier set in their attached WebChannel.id property
qtWebChannel = channel.objects.bridge
Vue.prototype.$QtCallBackDict = callBackDict // 用于注册从QT端的回调
Vue.prototype.$QtWebChannel = qtWebChannel
Vue.prototype.$request = request // 向QT端发送消息
console.log(qtWebChannel)
ChannelCallBack()
})
function request(func, data) {
Vue.prototype.$QtWebChannel.request(
JSON.stringify({ func: func, data: data })
)
}
function ChannelCallBack() {
console.log('初始化')
qtWebChannel.connectSignal.connect(connectSignalCallBack)
}
function connectSignalCallBack(jsonString) {
/*
res: {
code: 200/400 400就是后台有问题
func: string 在mount中载入
data: Dict 传入到view函数中
}
*/
console.info(callBackDict)
const res = JSON.parse(jsonString)
console.info(res)
if (res.code === 400) {
console.log(res)
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
return
}
const func = res.data.func
const data = res.data.data
callBackDict[func](data)
}
qwebchannel.js 自行添加
2.2 修改main.js引入全局QWebChannel
...
if (process.env.NODE_ENV === 'production') {
const { mockXHR } = require('../mock')
mockXHR()
}
/*
添加
载入QWebChannel
*/
import '@/utils/qt-request'
// set ElementUI lang to EN
Vue.use(ElementUI, { locale })
// 如果想要中文版 element-ui,按如下方式声明
// Vue.use(ElementUI)
...
2.3 修改table.vue
<script>
// 以前是如何的我就不写了 这是更改后的
export default {
filters: {
statusFilter(status) {
const statusMap = {
published: 'success',
draft: 'gray',
deleted: 'danger'
}
return statusMap[status]
}
},
data() {
return {
list: null,
listLoading: true,
row: 5
}
},
created() {
this.$QtCallBackDict.getTableData = this.fetchData
},
mounted() {
this.getTableData()
},
methods: {
fetchData(table_data) {
this.list = table_data
this.listLoading = false
},
getTableData() {
console.log(this.$QtWebChannel)
this.$request('getTableData', { row: this.row })
this.listLoading = true
}
}
}
</script>
2.4 自此WEB端修改完毕 npm run dev启动即可
3. PYTHON端开发
项目结构如下 绿色的是需要的
3.1 主函数入口
调用nodejs的服务器进行远程调试 主函数
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
"""
@File : demo_vue_element.py
@Author : Link
@Time : 2021/4/17 9:49
"""
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import QUrl, QTimer
from VueElementObject import VueElementObject
from PyQt5.QtWebChannel import QWebChannel
# 创建一个 application实例
app = QApplication(sys.argv)
win = QWidget()
win.setWindowTitle('Web页面中的JavaScript与 QWebEngineView交互例子')
# 创建一个垂直布局器
layout = QVBoxLayout()
win.setLayout(layout)
# 创建一个 QWebEngineView 对象
view = QWebEngineView()
htmlUrl = 'http://localhost:9528/'
# from qweb.dist import src_ui
# htmlUrl = 'qrc:/index.html'
channel = QWebChannel()
myObj = VueElementObject()
channel.registerObject("bridge", myObj)
view.load(QUrl(htmlUrl))
# 创建一个 QWebChannel对象,用来传递pyqt参数到JavaScript
view.page().setWebChannel(channel)
# 把QWebView和button加载到layout布局中
layout.addWidget(view)
# 显示窗口和运行app
win.show()
sys.exit(app.exec_())
3.2 其他函数
3.2.1 与VUE交互的主要函数
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
"""
@File : VueElementObject.py
@Author : Link
@Time : 2021/4/17 12:11
"""
from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal
import json
from qweb.utils import returnFailure
from qweb.view.table import get_table_data
class VueElementObject(QObject):
funcDict = {}
connectSignal = pyqtSignal(str)
def __init__(self):
super(VueElementObject, self).__init__()
self.table_init()
def table_init(self):
self.funcDict["getTableData"] = get_table_data
# @call_back_vue # 不能加上装饰 装饰器加上了后 在前端不会有request Object
@pyqtSlot(str)
def request(self, req: str):
print(req)
try:
request_data = json.loads(req)
func = request_data.get("func", None)
if func is None:
raise Exception("没有传入[func]函数名")
if func not in self.funcDict:
raise Exception("QT中不存在此函数用于调用")
data = self.funcDict[func](request_data)
if data is None:
return
if not isinstance(data, str):
raise Exception("返回值必须是一个json字符串类型")
self.connectSignal.emit(data)
except Exception as err:
self.connectSignal.emit(returnFailure(str(err)))
3.2.2 与返回给VUE端的数据结构
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
"""
@File : utils.py
@Author : Link
@Time : 2021/4/17 12:48
"""
import json
def returnSuccess(message, **kwargs):
return json.dumps({"data": kwargs, "message": message, 'code': 200})
def returnFailure(message, **kwargs):
return json.dumps({"data": kwargs, "message": message, 'code': 400})
3.2.3 和VUE table页面交互的函数
#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
"""
@File : table.py
@Author : Link
@Time : 2021/4/17 13:46
"""
from faker import Faker
from qweb.utils import returnSuccess
fake = Faker()
def generator_table(row: int):
data = []
for i in range(row):
data.append({
'id': i,
'title': fake.text(),
'author': fake.name(),
'display_time': fake.date_time().strftime("%Y-%m-%d %H:%M:%S"),
'pageviews': fake.random_int(),
'status': fake.random_sample(['published', 'draft', 'deleted'], 1)[0]
})
return data
def get_table_data(req: dict):
if req["func"] != 'getTableData':
raise Exception("func error")
return returnSuccess("success", func=req["func"], data=generator_table(req["data"]["row"]))
4.开发调试
5.完成打包
5.1 打包web端
使用vue-element-admin配置的打包命令 npm run build:prod 进行打包
打包后的项目文件如图 没有src.qrc哦 接下来就需要创建qrc文件
5.2 使用QT QRC文件打包web项目
在WEB项目打包后的位置 使用QT设计师 新建一个qrc文件
以/ 为前缀只添加一个路径
然后手动从各个文件夹 全部引入到qrc文件中如图
5.3 完成QRC文件的创建
qrc文件结构
<RCC>
<qresource prefix="/">
<file>favicon.ico</file>
<file>index.html</file>
<file>static/css/app.949a0224.css</file>
<file>static/css/chunk-61dbd1f1.9a9361c6.css</file>
<file>static/css/chunk-73d31757.c58e968f.css</file>
<file>static/css/chunk-385e7a5c.3c7f5ad9.css</file>
<file>static/css/chunk-76391674.94702ff7.css</file>
<file>static/css/chunk-elementUI.68c70ad5.css</file>
<file>static/css/chunk-libs.3dfb7769.css</file>
<file>static/fonts/element-icons.535877f5.woff</file>
<file>static/fonts/element-icons.732389de.ttf</file>
<file>static/img/404.a57b6f31.png</file>
<file>static/img/404_cloud.0f4bc32b.png</file>
<file>static/js/app.addc5b1b.js</file>
<file>static/js/chunk-2d0c8bf7.0b0747b8.js</file>
<file>static/js/chunk-2d0cfaef.f8c4497e.js</file>
<file>static/js/chunk-2d0d0f79.fd0ef435.js</file>
<file>static/js/chunk-2d0e4b0c.e753d0e8.js</file>
<file>static/js/chunk-2d0e4e1f.e61c70fd.js</file>
<file>static/js/chunk-2d0e944c.acc12e3a.js</file>
<file>static/js/chunk-2d226cab.bb682c8f.js</file>
<file>static/js/chunk-2d2104c6.a3d40e6f.js</file>
<file>static/js/chunk-61dbd1f1.beca85de.js</file>
<file>static/js/chunk-73d31757.6e68b9ff.js</file>
<file>static/js/chunk-385e7a5c.d1dde1bb.js</file>
<file>static/js/chunk-772faed3.b6b0959c.js</file>
<file>static/js/chunk-76391674.8f3ab814.js</file>
<file>static/js/chunk-elementUI.e8701db4.js</file>
<file>static/js/chunk-libs.7506166c.js</file>
</qresource>
</RCC>
5.4 集成封装
使用如下命令 pyrcc5.exe src.qrc -o src_ui.py 将src.qrc文件转为py文件
并将 src_ui.py 文件放入Python项目中引入,最终目录结构和代码如图
OK直接运行 可以启动后 就可以使用pyinstaller进行打包exe分发了 本人打包后是140M 比electron要小点 但是运气起来感觉不是很好看。。。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)