基本完成
This commit is contained in:
parent
904b59d71c
commit
4b6072f8fb
16 changed files with 276 additions and 820 deletions
|
@ -1,350 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import os, time, sys , importlib, sip
|
|
||||||
|
|
||||||
#__file__ 为此文件路径 , 在ipython里是测不出来的
|
|
||||||
pluginsManagerPath = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
#主脚本目录
|
|
||||||
mainPath = os.path.dirname(pluginsManagerPath)
|
|
||||||
#自定义插件目录
|
|
||||||
pluginsPath = os.path.join( mainPath, "Plugins")
|
|
||||||
#以后可能会有其他插件目录
|
|
||||||
AllPluginsPath = {"customer":pluginsPath}
|
|
||||||
#设置模块搜索路径
|
|
||||||
for key in AllPluginsPath :
|
|
||||||
if AllPluginsPath[key] not in sys.path:
|
|
||||||
sys.path.insert(0, AllPluginsPath[key])
|
|
||||||
|
|
||||||
from copy import deepcopy
|
|
||||||
|
|
||||||
from PyQt5.QtCore import *
|
|
||||||
from PyQt5.QtGui import *
|
|
||||||
from PyQt5.QtWidgets import *
|
|
||||||
|
|
||||||
from PluginManager.PluginStore import PluginStore
|
|
||||||
from PluginManager.PluginStore.StoreModel import FileModel
|
|
||||||
|
|
||||||
from Tools.pmf_myjson import *
|
|
||||||
|
|
||||||
"setting_flie -> From Tools.pmf_myjson , json写入的位置"
|
|
||||||
|
|
||||||
class PluginManager(QObject):
|
|
||||||
"""
|
|
||||||
管理插件的加载 , 卸载 , 文件的添加/删除监控.
|
|
||||||
"""
|
|
||||||
def __init__(self, parent=None, *args, **kwargs):
|
|
||||||
super(PluginManager, self).__init__(parent, *args, **kwargs)
|
|
||||||
self.__mw = parent
|
|
||||||
self.__initUI()
|
|
||||||
|
|
||||||
self.pluginDirs = {"pluginFolder": os.path.join(
|
|
||||||
os.path.abspath("./"),
|
|
||||||
"Plugins"), }
|
|
||||||
|
|
||||||
self.header = ["PlugName",
|
|
||||||
"Allow", "CreateTime", "ModifyTime"]
|
|
||||||
|
|
||||||
self.pluginsInfo = {
|
|
||||||
"StartModule": {},
|
|
||||||
|
|
||||||
}
|
|
||||||
# self.jsonPlugin :{插件名:{header参数}}
|
|
||||||
|
|
||||||
self.jsonPlugin = None
|
|
||||||
|
|
||||||
def __initUI(self):
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
mw = self.__mw
|
|
||||||
if mw.findChild(QMenuBar, "menuBar"):
|
|
||||||
# 插入到mainwindow的menuBar下 , 点击查看弹出插件加载情况窗体===
|
|
||||||
mw.menuPlugin = QAction("Plugin", self.__mw.menuBar,
|
|
||||||
triggered=self.__createPluginStoreDialog)
|
|
||||||
|
|
||||||
mw.menuBar.addAction(self.__mw.menuPlugin)
|
|
||||||
# 插入到mainwindow的menuBar下 , 点击查看弹出插件加载情况窗体===
|
|
||||||
else:
|
|
||||||
QMessageBox.information(mw, "", "主窗体没有菜单栏, 请先创建.")
|
|
||||||
|
|
||||||
# 文件监听器
|
|
||||||
|
|
||||||
self.model = FileModel(self)
|
|
||||||
self.model.setRootPath("./Plugins")
|
|
||||||
self.model.setFilter(QDir.Files)
|
|
||||||
self.model.setNameFilters(["Plugin*.py"])
|
|
||||||
self.model.setNameFilterDisables(False);
|
|
||||||
self.index = self.model.index("./Plugins")
|
|
||||||
|
|
||||||
self.model.directoryLoaded.connect(self.start)
|
|
||||||
|
|
||||||
def __createPluginStoreDialog(self):
|
|
||||||
"""
|
|
||||||
显示插件加载情况的 窗体.
|
|
||||||
"""
|
|
||||||
if not hasattr(self, "dia"):
|
|
||||||
self.dia = PluginStore.PluginStore(self, self.__mw)
|
|
||||||
|
|
||||||
self.dia.show()
|
|
||||||
|
|
||||||
|
|
||||||
def m_rowsRemoved(self, index, first, last):
|
|
||||||
"""
|
|
||||||
文件被删除或重命名时候被调用.
|
|
||||||
"""
|
|
||||||
print("removeName:", self.model.index(first, 0, index).data(),first )
|
|
||||||
mod = (self.model.index(first, 0, index).data())[:-3]
|
|
||||||
|
|
||||||
self.unload(mod)
|
|
||||||
self.pluginsInfo["StartModule"].pop(mod)
|
|
||||||
self.delJson(self.jsonPlugin , self.pluginsInfo["StartModule"])
|
|
||||||
|
|
||||||
# pop的步骤u已经在deljson中执行
|
|
||||||
# self.jsonPlugin.pop(mod)
|
|
||||||
|
|
||||||
def m_rowsInserted(self, index, first, last):
|
|
||||||
"""
|
|
||||||
文件增加或重命名时候被调用.
|
|
||||||
"""
|
|
||||||
print("insertName:", self.model.index(first, 0, index).data(), first)
|
|
||||||
f = self.model.index(first, 0, index).data()
|
|
||||||
mod = f[:-3]
|
|
||||||
|
|
||||||
fullPath = os.path.join(self.pluginDirs["pluginFolder"], f)
|
|
||||||
self.pluginsInfo["StartModule"][mod] = {"path": fullPath}
|
|
||||||
mod, data = self.addJson(fullPath, mod)
|
|
||||||
|
|
||||||
self.jsonPlugin[mod] = data
|
|
||||||
|
|
||||||
self.load(mod)
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
"""
|
|
||||||
self.model 异步加载完成之后开始调用 self.startGetPlugin.
|
|
||||||
"""
|
|
||||||
self.jsonPlugin = self.startGetPlugin(self.pluginDirs['pluginFolder'])
|
|
||||||
# print("jsonPlugin:", self.jsonPlugin,"\n",
|
|
||||||
# "pluginsModule:", self.pluginsInfo)
|
|
||||||
self.loadAll()
|
|
||||||
|
|
||||||
self.model.rowsAboutToBeRemoved.connect(self.m_rowsRemoved)
|
|
||||||
self.model.rowsInserted.connect(self.m_rowsInserted)
|
|
||||||
self.model.directoryLoaded.disconnect(self.start)
|
|
||||||
self.__createPluginStoreDialog()
|
|
||||||
|
|
||||||
def startGetPlugin(self, pluginFolder: "./Plugins", CHANGE=False) -> "FoJson":
|
|
||||||
"""
|
|
||||||
1 . 程序启动加载插件.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
jsonPlugin = mfunc_readJson(setting_flie)
|
|
||||||
|
|
||||||
except:
|
|
||||||
jsonPlugin = {}
|
|
||||||
|
|
||||||
pluginInfo = {}
|
|
||||||
|
|
||||||
rowCount = self.model.rowCount(self.index)
|
|
||||||
|
|
||||||
for row in range(rowCount):
|
|
||||||
index = self.model.index(row, 0, self.index)
|
|
||||||
# 文件名
|
|
||||||
f = index.data()
|
|
||||||
# 去掉后缀 , 加入模块
|
|
||||||
module = f[:-3]
|
|
||||||
fullPath = os.path.join(pluginFolder, f)
|
|
||||||
|
|
||||||
pluginInfo[module] = {"path": fullPath}
|
|
||||||
try:
|
|
||||||
if module not in jsonPlugin:
|
|
||||||
self.addJson(fullPath, module)
|
|
||||||
except:
|
|
||||||
self.addJson(fullPath, module)
|
|
||||||
|
|
||||||
if CHANGE is False:
|
|
||||||
self.pluginsInfo["StartModule"] = deepcopy(pluginInfo)
|
|
||||||
|
|
||||||
jsonPlugin = self.delJson(jsonPlugin, pluginInfo)
|
|
||||||
|
|
||||||
# print("jsonPlugin",jsonPlugin, "\n", "pluginInfo",pluginInfo )
|
|
||||||
|
|
||||||
return jsonPlugin
|
|
||||||
|
|
||||||
def addJson(self, fullPath, module) -> "ToJson":
|
|
||||||
"""1.1写入插件 的json配置."""
|
|
||||||
# 插件创建时间
|
|
||||||
_ctime = time.localtime(os.stat(fullPath).st_ctime)
|
|
||||||
ctime = time.strftime("%Y-%m-%d-%H:%M:%S", _ctime)
|
|
||||||
# 插件修改时间
|
|
||||||
_mtime = time.localtime(os.stat(fullPath).st_mtime)
|
|
||||||
mtime = time.strftime("%Y-%m-%d-%H:%M:%S", _mtime)
|
|
||||||
# 写入配置
|
|
||||||
data = {
|
|
||||||
self.header[1]: True, # allow
|
|
||||||
self.header[2]: ctime, # cteateTime
|
|
||||||
self.header[3]: mtime, # modifyTime
|
|
||||||
}
|
|
||||||
mfunc_AKrCVJson(module, data , self=self)
|
|
||||||
|
|
||||||
return module, data
|
|
||||||
|
|
||||||
def delJson(self, jsonPlugin, pluginInfo) -> "ToJson":
|
|
||||||
"""
|
|
||||||
1.2删除插件 的json配置.
|
|
||||||
"""
|
|
||||||
# 添加完重新加载一遍看是否有插件删除
|
|
||||||
if jsonPlugin == {}:
|
|
||||||
jsonPlugin = mfunc_readJson(setting_flie)
|
|
||||||
|
|
||||||
if len(jsonPlugin) - len(pluginInfo):
|
|
||||||
long, short = jsonPlugin, pluginInfo
|
|
||||||
else:
|
|
||||||
long, short = pluginInfo, jsonPlugin
|
|
||||||
|
|
||||||
with open(setting_flie, 'a+', encoding='utf-8') as f:
|
|
||||||
# 被删除的插件集合
|
|
||||||
delPlugin = set(long) - set(short)
|
|
||||||
for item in delPlugin:
|
|
||||||
jsonPlugin.pop(item)
|
|
||||||
# 写入配置
|
|
||||||
mfunc_reDumpJson(f, jsonPlugin)
|
|
||||||
|
|
||||||
return jsonPlugin
|
|
||||||
|
|
||||||
# 加载所有插件
|
|
||||||
def loadAll(self):
|
|
||||||
"""
|
|
||||||
2.加载所有模块.
|
|
||||||
"""
|
|
||||||
for mod in self.jsonPlugin:
|
|
||||||
if self.jsonPlugin[mod]["Allow"]:
|
|
||||||
try:
|
|
||||||
self.load(mod)
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
self.pluginsInfo["StartModule"][mod]["active"] = False
|
|
||||||
|
|
||||||
# 加载插件
|
|
||||||
def load(self, mod: "str"):
|
|
||||||
"""
|
|
||||||
2.1 载入模块.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# 动态载入模块
|
|
||||||
_pluginModule = importlib.import_module(mod)
|
|
||||||
|
|
||||||
except:
|
|
||||||
QMessageBox.information(self.__mw,
|
|
||||||
"模块导入异常",
|
|
||||||
"请在%s.py检查模块."%mod)
|
|
||||||
|
|
||||||
self.pluginsInfo["StartModule"][mod]["active"] = False
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
self.instantiation(mod, _pluginModule)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def instantiation(self , mod, moduleObj , NeedRplace = False):
|
|
||||||
"""
|
|
||||||
1.--实例化类.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
className = getattr(moduleObj, "className")
|
|
||||||
pluginClass = getattr(moduleObj, className )
|
|
||||||
except:
|
|
||||||
self.pluginsInfo[mod]["active"] = False
|
|
||||||
QMessageBox.information(self.__mw,
|
|
||||||
"插件加载错误",
|
|
||||||
"请在%s.py全局指定className值." % mod)
|
|
||||||
return False
|
|
||||||
# 如果是替换对象需求 ,和初始化
|
|
||||||
|
|
||||||
# 实例化类
|
|
||||||
pluginObject = pluginClass(self.__mw)
|
|
||||||
pluginObject.setObjectName(mod)
|
|
||||||
|
|
||||||
self.pluginsInfo["StartModule"][mod]["active"] = True
|
|
||||||
self.pluginsInfo["StartModule"][mod]["pluginClass"] = pluginClass
|
|
||||||
self.pluginsInfo["StartModule"][mod]["parent"] = pluginObject.parent()
|
|
||||||
|
|
||||||
if not NeedRplace:
|
|
||||||
#TODO:其他接口
|
|
||||||
layout = pluginObject.getParentLayout()
|
|
||||||
layout.addWidget(pluginObject)
|
|
||||||
|
|
||||||
self.pluginsInfo["StartModule"][mod]["layout"] = layout
|
|
||||||
self.pluginsInfo["StartModule"][mod]["old"] = pluginObject
|
|
||||||
else:
|
|
||||||
self.pluginsInfo["StartModule"][mod]["new"] = pluginObject
|
|
||||||
return pluginObject
|
|
||||||
# 卸载插件
|
|
||||||
def unload(self, mod: "str"):
|
|
||||||
"""
|
|
||||||
卸载插件 , 移除模块.
|
|
||||||
"""
|
|
||||||
if mod in sys.modules:
|
|
||||||
self.pluginsInfo["StartModule"][mod]["active"] = False
|
|
||||||
#删除对象
|
|
||||||
objInfo = self.findOldObj(mod)
|
|
||||||
oldObj, layout = objInfo["oldObj"], objInfo["layout"]
|
|
||||||
print(oldObj.objectName()+" be unload")
|
|
||||||
|
|
||||||
sip.delete(oldObj)
|
|
||||||
|
|
||||||
# layout.removeWidget(oldObj)
|
|
||||||
self.pluginsInfo["StartModule"][mod]["old"] = None
|
|
||||||
sys.modules.pop(mod)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
# 重载插件
|
|
||||||
def reload(self, mod):
|
|
||||||
if mod in sys.modules:
|
|
||||||
#TODO: 旧对象替换
|
|
||||||
print("reload")
|
|
||||||
moduleObj = sys.modules[mod]
|
|
||||||
button = QPushButton("哈哈")
|
|
||||||
objInfo = self.findOldObj(mod, moduleObj = moduleObj , needRplace = True)
|
|
||||||
oldObj, newObj, layout = objInfo["oldObj"], objInfo["newObj"], objInfo["layout"]
|
|
||||||
|
|
||||||
print(layout.replaceWidget(oldObj, newObj ))
|
|
||||||
self.pluginsInfo["StartModule"][mod]["old"] = newObj
|
|
||||||
print(self.pluginsInfo["StartModule"][mod])
|
|
||||||
sip.delete(oldObj)
|
|
||||||
else:
|
|
||||||
self.load(mod)
|
|
||||||
|
|
||||||
def findOldObj(self, mod, moduleObj=None, needRplace = False):
|
|
||||||
"""
|
|
||||||
找到需要删除或替换的对象.
|
|
||||||
"""
|
|
||||||
oldObj = self.pluginsInfo["StartModule"][mod]["old"]
|
|
||||||
parentWidget = self.pluginsInfo["StartModule"][mod]["parent"]
|
|
||||||
layout = self.pluginsInfo["StartModule"][mod]["layout"]
|
|
||||||
pluginClass = self.pluginsInfo["StartModule"][mod]["pluginClass"]
|
|
||||||
if needRplace:
|
|
||||||
if moduleObj==None:
|
|
||||||
QMessageBox.information(self.__mw,
|
|
||||||
"错误",
|
|
||||||
"请传入moduleObj值.")
|
|
||||||
else:
|
|
||||||
newObj = self.instantiation(mod, moduleObj, needRplace)
|
|
||||||
else:
|
|
||||||
newObj = None
|
|
||||||
|
|
||||||
return {"oldObj" :oldObj ,
|
|
||||||
"newObj" :newObj ,
|
|
||||||
"parentWidget":parentWidget,
|
|
||||||
"layout" :layout,
|
|
||||||
"pluginClass" :pluginClass,
|
|
||||||
}
|
|
||||||
|
|
||||||
# 卸载所有插件
|
|
||||||
def unloadAll(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def PluginToInterFace(self):
|
|
||||||
pass
|
|
|
@ -1,256 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
import os , time , imp
|
|
||||||
from copy import deepcopy
|
|
||||||
from importlib.machinery import SourceFileLoader
|
|
||||||
|
|
||||||
|
|
||||||
from PyQt5.QtCore import *
|
|
||||||
from PyQt5.QtGui import *
|
|
||||||
from PyQt5.QtWidgets import *
|
|
||||||
|
|
||||||
from PluginManager import PluginStore
|
|
||||||
|
|
||||||
from Tools.pmf_myjson import *
|
|
||||||
|
|
||||||
"setting_flie -> From Tools.pmf_myjson , json写入的位置"
|
|
||||||
|
|
||||||
class PluginManager(QObject):
|
|
||||||
|
|
||||||
def __init__(self, parent = None , *args, **kwargs):
|
|
||||||
super(PluginManager, self).__init__(parent , *args, **kwargs)
|
|
||||||
self.__mw = parent
|
|
||||||
self.__initUI()
|
|
||||||
|
|
||||||
self.pluginDirs = {"pluginPath": os.path.join("./", "Plugins"),}
|
|
||||||
|
|
||||||
self.header = ["PlugName",
|
|
||||||
"Allow" , "CreateTime", "ModifyTime"]
|
|
||||||
|
|
||||||
self.changePlugin = {
|
|
||||||
"StartModule" :{},
|
|
||||||
"NewModule" :None,
|
|
||||||
"Load" :{},
|
|
||||||
"del" :set(),
|
|
||||||
"rename" :[],
|
|
||||||
}
|
|
||||||
# self.existPlugin :{插件名:{header参数}}
|
|
||||||
# self.pluginsModule :{插件名:{path:插件路径}}
|
|
||||||
|
|
||||||
self.existPlugin, self.pluginsModule = None, None
|
|
||||||
self.existPlugin, self.pluginsModule = \
|
|
||||||
self.getPluginModules(self.pluginDirs['pluginPath'])
|
|
||||||
# print("existPlugin:", self.existPlugin,"\n",
|
|
||||||
# "pluginsModule:", self.pluginsModule)
|
|
||||||
|
|
||||||
#载入模块
|
|
||||||
self.loadAll()
|
|
||||||
|
|
||||||
# 文件监听器
|
|
||||||
|
|
||||||
self.model = QFileSystemModel()
|
|
||||||
self.model.setRootPath("./Plugins")
|
|
||||||
self.model.setFilter( QDir.Files )
|
|
||||||
self.model.setNameFilters(["Plugin*.py"])
|
|
||||||
index = self.model.index("./Plugins")
|
|
||||||
print(self.model.size(index))
|
|
||||||
self.model.setNameFilterDisables(False);
|
|
||||||
|
|
||||||
self.model.rowsRemoved.connect(self.m_rowsRemoved)
|
|
||||||
self.model.directoryLoaded.connect(lambda :self.model.size(index) )
|
|
||||||
|
|
||||||
self.tree = QTreeView()
|
|
||||||
self.tree.setModel(self.model)
|
|
||||||
self.tree.setRootIndex(index);
|
|
||||||
self.tree.show()
|
|
||||||
def m_rowsRemoved(self, index,first, last):
|
|
||||||
print(index)
|
|
||||||
# print(self.model.size())
|
|
||||||
# self.watcher = QFileSystemWatcher(
|
|
||||||
# ["./Plugins"],
|
|
||||||
# directoryChanged = self.m_directoryChanged
|
|
||||||
# )
|
|
||||||
|
|
||||||
def m_directoryChanged(self):
|
|
||||||
self.existPlugin, self.pluginsModule = \
|
|
||||||
self.getPluginModules(self.pluginDirs['pluginPath'], True)
|
|
||||||
|
|
||||||
del self.changePlugin["NewModule"]
|
|
||||||
self.changePlugin["NewModule"] = deepcopy(self.pluginsModule)
|
|
||||||
|
|
||||||
StartModuleLen = len(self.changePlugin["StartModule"])
|
|
||||||
NewModuleLen = len(self.changePlugin["NewModule"])
|
|
||||||
LoadLen = len(self.changePlugin["Load"])
|
|
||||||
|
|
||||||
NewSucModuleLen = NewModuleLen \
|
|
||||||
- StartModuleLen \
|
|
||||||
- LoadLen
|
|
||||||
|
|
||||||
|
|
||||||
if NewSucModuleLen>0:
|
|
||||||
|
|
||||||
moduleSet = set(self.changePlugin["NewModule"]) \
|
|
||||||
- set(self.changePlugin["StartModule"])\
|
|
||||||
- set(self.changePlugin["Load"]) \
|
|
||||||
|
|
||||||
module = moduleSet.pop()
|
|
||||||
|
|
||||||
if not self.load(module):
|
|
||||||
self.changePlugin["Load"]["Success"] = False
|
|
||||||
else:
|
|
||||||
self.changePlugin["Load"]["Success"] = True
|
|
||||||
|
|
||||||
elif NewSucModuleLen<0:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __initUI(self):
|
|
||||||
if self.__mw.findChild(QMenuBar, "menuBar"):
|
|
||||||
|
|
||||||
self.__mw.menuPlugin = QAction("Plugin", self.__mw.menuBar,
|
|
||||||
triggered = self.__createPluginStoreDialog)
|
|
||||||
self.__mw.menuBar.addAction(self.__mw.menuPlugin)
|
|
||||||
|
|
||||||
else:
|
|
||||||
QMessageBox.information(self.__mw, "", "主窗体没有菜单栏, 请先创建.")
|
|
||||||
|
|
||||||
def __createPluginStoreDialog(self):
|
|
||||||
"""
|
|
||||||
显示插件加载情况的 窗体.
|
|
||||||
"""
|
|
||||||
dia = PluginStore.PluginStore(self, self.__mw)
|
|
||||||
|
|
||||||
dia.exec_()
|
|
||||||
|
|
||||||
def getPluginModules(self, pluginPath:"./Plugins" , CHANGE=False)->"FoJson":
|
|
||||||
|
|
||||||
"""
|
|
||||||
Public method to get a list of plugin modules.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
existPlugin = mfunc_readJson(setting_flie)
|
|
||||||
|
|
||||||
except:
|
|
||||||
existPlugin=None
|
|
||||||
|
|
||||||
pluginFiles = {} if CHANGE is False else self.pluginsModule
|
|
||||||
|
|
||||||
for f in os.listdir(pluginPath):
|
|
||||||
# 插件名称的有效性检查
|
|
||||||
if f.endswith(".py") and f.startswith("Plugin"):
|
|
||||||
# 去掉后缀 , 加入模块
|
|
||||||
module = f[:-3]
|
|
||||||
|
|
||||||
fullPath = os.path.join( pluginPath , f)
|
|
||||||
# 增删改的变化
|
|
||||||
if module not in self.changePlugin["StartModule"]:
|
|
||||||
pluginFiles[module] = {"path" :fullPath}
|
|
||||||
|
|
||||||
if "active" not in pluginFiles[module]:
|
|
||||||
pluginFiles[module]["active"] = False
|
|
||||||
print("---" , )
|
|
||||||
# 判断模块不在json文件中
|
|
||||||
if module not in existPlugin:
|
|
||||||
self.addJson(fullPath, module)
|
|
||||||
|
|
||||||
self.delJson(existPlugin, pluginFiles)
|
|
||||||
|
|
||||||
if CHANGE is False:
|
|
||||||
self.changePlugin["StartModule"] = deepcopy(pluginFiles)
|
|
||||||
|
|
||||||
return existPlugin, pluginFiles
|
|
||||||
|
|
||||||
def addJson(self, fullPath , module )->"ToJson":
|
|
||||||
# 插件创建时间
|
|
||||||
_ctime = time.localtime(os.stat(fullPath).st_ctime)
|
|
||||||
ctime = time.strftime("%Y-%m-%d-%H:%M:%S",_ctime)
|
|
||||||
# 插件修改时间
|
|
||||||
_mtime = time.localtime(os.stat(fullPath).st_mtime)
|
|
||||||
mtime = time.strftime("%Y-%m-%d-%H:%M:%S",_mtime)
|
|
||||||
|
|
||||||
# 写入配置
|
|
||||||
mfunc_AKrCVJson( module ,
|
|
||||||
{
|
|
||||||
self.header[1]: True, #allow
|
|
||||||
self.header[2]: ctime,#cteateTime
|
|
||||||
self.header[3]: mtime,#modifyTime
|
|
||||||
} ,
|
|
||||||
self = self)
|
|
||||||
|
|
||||||
def delJson(self , existPlugin, pluginFiles)->"ToJson":
|
|
||||||
|
|
||||||
"""
|
|
||||||
删除插件 的json配置.
|
|
||||||
"""
|
|
||||||
# 获取最终json配置
|
|
||||||
# self.existPlugin = mfunc_readJson(setting_flie)
|
|
||||||
# 添加完重新加载一遍看是否有插件删除
|
|
||||||
if existPlugin==None:
|
|
||||||
existPlugin = mfunc_readJson(setting_flie)
|
|
||||||
|
|
||||||
if len(existPlugin)>len(pluginFiles):
|
|
||||||
with open( setting_flie ,'a+' , encoding='utf-8') as f:
|
|
||||||
# 被删除的插件集合
|
|
||||||
delPlugin = set(existPlugin)-set(pluginFiles)
|
|
||||||
for item in delPlugin:
|
|
||||||
existPlugin.pop(item)
|
|
||||||
self.changePlugin["del"]
|
|
||||||
# 写入配置
|
|
||||||
mfunc_reDumpJson(f, existPlugin)
|
|
||||||
|
|
||||||
# 加载所有插件
|
|
||||||
def loadAll(self):
|
|
||||||
for mod in self.existPlugin:
|
|
||||||
if self.existPlugin[mod]["Allow"] \
|
|
||||||
and not self.pluginsModule[mod]["active"]:
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.load(mod)
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# 加载插件
|
|
||||||
def load(self , mod:"str"):
|
|
||||||
|
|
||||||
try:
|
|
||||||
# print(self.pluginsModule[mod]["path"])
|
|
||||||
# python内置函数, 把.py 当做模块载入
|
|
||||||
_pluginModule = SourceFileLoader( mod ,
|
|
||||||
self.pluginsModule[mod]["path"]).load_module()
|
|
||||||
# _pluginModule=imp.load_source(mod, self.pluginsModule[mod]["path"])
|
|
||||||
except:
|
|
||||||
# QMessageBox.information(self.__mw,
|
|
||||||
# "模块导入异常",
|
|
||||||
# "请在%s.py检查模块."%mod)
|
|
||||||
|
|
||||||
self.pluginsModule[mod]["active"] = False
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
|
||||||
className = getattr(_pluginModule, "className")
|
|
||||||
pluginClass = getattr(_pluginModule, className )
|
|
||||||
except:
|
|
||||||
self.pluginsModule[mod]["active"] = False
|
|
||||||
QMessageBox.information(self.__mw,
|
|
||||||
"插件加载错误",
|
|
||||||
"请在%s.py全局指定className值."%mod)
|
|
||||||
return False
|
|
||||||
# 实例化类
|
|
||||||
pluginObject = pluginClass()
|
|
||||||
pluginObject.setObjectName(className)
|
|
||||||
|
|
||||||
self.__mw.verticalLayout.addWidget(pluginObject)
|
|
||||||
self.pluginsModule[mod]["active"] = True
|
|
||||||
|
|
||||||
return True
|
|
||||||
# 卸载插件
|
|
||||||
def unload(self, mod:"str"):
|
|
||||||
# self.__mw.findchild()
|
|
||||||
print(sys.modules[mod], mod)
|
|
||||||
print(self.__mw.findChild(QWidget, mod))
|
|
||||||
#TODO:
|
|
||||||
return True
|
|
||||||
|
|
||||||
# 卸载所有插件
|
|
||||||
def unloadAll(self):
|
|
||||||
pass
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"""
|
"""
|
||||||
管理插件的加载 , 卸载 , 监控文件的添加/删除.
|
管理插件的加载 , 卸载 , 监控文件的添加/删除.
|
||||||
"""
|
"""
|
||||||
import os, time, sys , importlib, sip
|
import os, time, sys , importlib, sip, traceback
|
||||||
# ==添加插件的搜索路径==
|
# ==添加插件的搜索路径==
|
||||||
#__file__ 为此文件路径 , 在ipython里是测不出来的
|
#__file__ 为此文件路径 , 在ipython里是测不出来的
|
||||||
pluginsManagerPath = os.path.dirname(os.path.abspath(__file__))
|
pluginsManagerPath = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
@ -62,10 +62,10 @@ class PluginManager(QObject):
|
||||||
mw = self.__mw
|
mw = self.__mw
|
||||||
if mw.findChild(QMenuBar, "menuBar"):
|
if mw.findChild(QMenuBar, "menuBar"):
|
||||||
# 插入到mainwindow的menuBar下 , 点击查看弹出插件加载情况窗体===
|
# 插入到mainwindow的menuBar下 , 点击查看弹出插件加载情况窗体===
|
||||||
mw.menuPlugin = QAction("Plugin", self.__mw.menuBar,
|
mw.menuPlugin = QAction("Plugin", mw.menuBar,
|
||||||
triggered=self.__createPluginStoreDialog)
|
triggered=self.__createPluginStoreDialog)
|
||||||
|
|
||||||
mw.menuBar.addAction(self.__mw.menuPlugin)
|
mw.menuBar.addAction(mw.menuPlugin)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
QMessageBox.information(mw, "", "主窗体没有菜单栏, 请先创建.")
|
QMessageBox.information(mw, "", "主窗体没有菜单栏, 请先创建.")
|
||||||
|
@ -156,16 +156,16 @@ class PluginManager(QObject):
|
||||||
fullPath = os.path.join(pluginFolder, f)
|
fullPath = os.path.join(pluginFolder, f)
|
||||||
|
|
||||||
pluginInfo[module] = {"path": fullPath}
|
pluginInfo[module] = {"path": fullPath}
|
||||||
try:
|
|
||||||
if module not in jsonPlugin:
|
if module not in jsonPlugin:
|
||||||
self.addJson(fullPath, module)
|
module, data = self.addJson(fullPath, module)
|
||||||
except:
|
jsonPlugin[module]=data
|
||||||
self.addJson(fullPath, module)
|
|
||||||
|
|
||||||
if CHANGE is False:
|
if CHANGE is False:
|
||||||
self.pluginsInfo["StartModule"] = deepcopy(pluginInfo)
|
self.pluginsInfo["StartModule"] = deepcopy(pluginInfo)
|
||||||
|
|
||||||
jsonPlugin = self.delJson(jsonPlugin, pluginInfo)
|
jsonPlugin = self.delJson({}, pluginInfo)
|
||||||
|
|
||||||
# print("jsonPlugin",jsonPlugin, "\n", "pluginInfo",pluginInfo )
|
# print("jsonPlugin",jsonPlugin, "\n", "pluginInfo",pluginInfo )
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ class PluginManager(QObject):
|
||||||
_pluginModule = importlib.import_module(mod)
|
_pluginModule = importlib.import_module(mod)
|
||||||
|
|
||||||
except:
|
except:
|
||||||
import traceback
|
|
||||||
errmsg = traceback.format_exc()
|
errmsg = traceback.format_exc()
|
||||||
|
|
||||||
QMessageBox.information(self.__mw,
|
QMessageBox.information(self.__mw,
|
||||||
|
@ -264,26 +264,34 @@ class PluginManager(QObject):
|
||||||
className = getattr(moduleObj, "className")
|
className = getattr(moduleObj, "className")
|
||||||
pluginClass = getattr(moduleObj, className )
|
pluginClass = getattr(moduleObj, className )
|
||||||
except:
|
except:
|
||||||
self.pluginsInfo[mod]["active"] = False
|
self.pluginsInfo["StartModule"][mod]["active"] = False
|
||||||
|
errmsg = traceback.format_exc()
|
||||||
QMessageBox.information(self.__mw,
|
QMessageBox.information(self.__mw,
|
||||||
"插件加载错误",
|
"插件加载错误",
|
||||||
"请在%s.py全局指定className值." % mod)
|
"%s ,请在%s.py全局指定className值." % (errmsg, mod))
|
||||||
return False
|
return False
|
||||||
# 如果是替换对象需求 ,和初始化
|
# 如果是替换对象需求 ,和初始化
|
||||||
|
|
||||||
# 实例化类
|
# 实例化类
|
||||||
pluginObject = pluginClass(self.__mw)
|
try:
|
||||||
pluginObject.setObjectName(mod)
|
pluginObject = pluginClass(self.__mw)
|
||||||
|
pluginObject.setObjectName(mod)
|
||||||
|
|
||||||
self.pluginsInfo["StartModule"][mod]["active"] = True
|
self.pluginsInfo["StartModule"][mod]["active"] = True
|
||||||
self.pluginsInfo["StartModule"][mod]["pluginClass"] = pluginClass
|
self.pluginsInfo["StartModule"][mod]["pluginClass"] = pluginClass
|
||||||
self.pluginsInfo["StartModule"][mod]["parent"] = pluginObject.parent()
|
self.pluginsInfo["StartModule"][mod]["parent"] = pluginObject.parent()
|
||||||
|
except:
|
||||||
|
|
||||||
|
self.pluginsInfo["StartModule"][mod]["active"] = False
|
||||||
|
errmsg = traceback.format_exc()
|
||||||
|
QMessageBox.information(self.__mw,
|
||||||
|
"插件加载错误",
|
||||||
|
"%s ,请在%s.py全局指定className值." % (errmsg, mod))
|
||||||
|
|
||||||
if not NeedRplace:
|
if not NeedRplace:
|
||||||
#TODO:其他接口
|
#TODO:其他接口
|
||||||
layout = pluginObject.getParentLayout()
|
layout = pluginObject.getParentLayout()
|
||||||
layout.addWidget(pluginObject)
|
pluginObject.toInterface()
|
||||||
|
|
||||||
self.pluginsInfo["StartModule"][mod]["layout"] = layout
|
self.pluginsInfo["StartModule"][mod]["layout"] = layout
|
||||||
self.pluginsInfo["StartModule"][mod]["old"] = pluginObject
|
self.pluginsInfo["StartModule"][mod]["old"] = pluginObject
|
||||||
else:
|
else:
|
||||||
|
@ -300,8 +308,15 @@ class PluginManager(QObject):
|
||||||
print("reload")
|
print("reload")
|
||||||
importlib.reload(sys.modules[mod])
|
importlib.reload(sys.modules[mod])
|
||||||
moduleObj = sys.modules[mod]
|
moduleObj = sys.modules[mod]
|
||||||
|
try:
|
||||||
|
objInfo = self.findOldObj(mod, moduleObj , True)
|
||||||
|
except:
|
||||||
|
errmsg = traceback.format_exc()
|
||||||
|
|
||||||
|
QMessageBox.information(self.__mw,
|
||||||
|
"模块导入异常",
|
||||||
|
"%s,请在%s.py检查模块."%(errmsg,mod ))
|
||||||
|
|
||||||
objInfo = self.findOldObj(mod, moduleObj , True)
|
|
||||||
oldObj, newObj, layout = objInfo["oldObj"],\
|
oldObj, newObj, layout = objInfo["oldObj"],\
|
||||||
objInfo["newObj"],\
|
objInfo["newObj"],\
|
||||||
objInfo["layout"]
|
objInfo["layout"]
|
||||||
|
@ -309,7 +324,7 @@ class PluginManager(QObject):
|
||||||
# 新对象替换旧对象 , 并把地址赋值给旧对象
|
# 新对象替换旧对象 , 并把地址赋值给旧对象
|
||||||
layout.replaceWidget(oldObj, newObj )
|
layout.replaceWidget(oldObj, newObj )
|
||||||
self.pluginsInfo["StartModule"][mod]["old"] = newObj
|
self.pluginsInfo["StartModule"][mod]["old"] = newObj
|
||||||
|
oldObj.flag="reload"
|
||||||
sip.delete(oldObj)
|
sip.delete(oldObj)
|
||||||
else:
|
else:
|
||||||
self.load(mod)
|
self.load(mod)
|
||||||
|
@ -352,7 +367,7 @@ class PluginManager(QObject):
|
||||||
#删除对象
|
#删除对象
|
||||||
objInfo = self.findOldObj(mod)
|
objInfo = self.findOldObj(mod)
|
||||||
oldObj = objInfo["oldObj"]
|
oldObj = objInfo["oldObj"]
|
||||||
|
oldObj.flag="unload"
|
||||||
sip.delete(oldObj)
|
sip.delete(oldObj)
|
||||||
|
|
||||||
self.pluginsInfo["StartModule"][mod]["old"] = None
|
self.pluginsInfo["StartModule"][mod]["old"] = None
|
||||||
|
|
|
@ -117,7 +117,6 @@ class PluginStore(QDialog, Ui_Dialog):
|
||||||
if msg==QMessageBox.Yes:
|
if msg==QMessageBox.Yes:
|
||||||
self.manager.unload(mod)
|
self.manager.unload(mod)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
self.manager.reload(mod)
|
self.manager.reload(mod)
|
||||||
|
|
||||||
# 右键菜单重载和卸载 , 默认的是选行的第0列
|
# 右键菜单重载和卸载 , 默认的是选行的第0列
|
||||||
|
|
|
@ -1,10 +1,4 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
#import sys, os
|
"""
|
||||||
#pluginsManagetPath = os.path.dirname(os.path.abspath(__file__))
|
插件的加载 , 重载 , 卸载模块 , 配置文件模块.
|
||||||
#mainPath = os.path.dirname(pluginsManagetPath)
|
"""
|
||||||
#pluginsPath = os.path.join(pluginsManagetPath, "Plugins")
|
|
||||||
#
|
|
||||||
#for i in [pluginsPath]:
|
|
||||||
# print(mainPath, pluginsManagetPath, pluginsPath)
|
|
||||||
# sys.path.insert(0, i)
|
|
||||||
# print("add")
|
|
||||||
|
|
|
@ -1,17 +1,32 @@
|
||||||
{
|
{
|
||||||
"PluginPage1": {
|
"PluginPage0_inMainLayout": {
|
||||||
"Allow": false,
|
"Allow": true,
|
||||||
"CreateTime": "2018-09-18-18:44:18",
|
"CreateTime": "2018-09-18-18:44:18",
|
||||||
"ModifyTime": "2018-09-23-20:13:56"
|
"ModifyTime": "2018-09-24-15:58:45"
|
||||||
},
|
},
|
||||||
"PluginPage2": {
|
"PluginPage1_addTab3": {
|
||||||
|
"Allow": true,
|
||||||
|
"CreateTime": "2018-09-24-17:48:29",
|
||||||
|
"ModifyTime": "2018-09-24-18:24:48"
|
||||||
|
},
|
||||||
|
"PluginPage1_addTab4": {
|
||||||
|
"Allow": true,
|
||||||
|
"CreateTime": "2018-09-24-18:17:19",
|
||||||
|
"ModifyTime": "2018-09-24-18:24:22"
|
||||||
|
},
|
||||||
|
"PluginPage2_error": {
|
||||||
"Allow": false,
|
"Allow": false,
|
||||||
"CreateTime": "2018-09-18-18:45:14",
|
"CreateTime": "2018-09-18-18:45:14",
|
||||||
"ModifyTime": "2018-09-19-18:16:08"
|
"ModifyTime": "2018-09-19-18:16:08"
|
||||||
},
|
},
|
||||||
"Pluginmmm": {
|
"PluginPage3_addAction2": {
|
||||||
"Allow": true,
|
"Allow": true,
|
||||||
"CreateTime": "2018-09-23-20:57:37",
|
"CreateTime": "2018-09-24-20:54:48",
|
||||||
"ModifyTime": "2018-09-23-20:13:56"
|
"ModifyTime": "2018-09-24-20:57:03"
|
||||||
|
},
|
||||||
|
"PluginPage3_addAction1": {
|
||||||
|
"Allow": true,
|
||||||
|
"CreateTime": "2018-09-24-18:26:10",
|
||||||
|
"ModifyTime": "2018-09-24-20:50:02"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE Project SYSTEM "Project-6.0.dtd">
|
<!DOCTYPE Project SYSTEM "Project-6.0.dtd">
|
||||||
<!-- eric project file for project Plugins -->
|
<!-- eric project file for project Plugins -->
|
||||||
<!-- Saved: 2018-09-21, 22:53:13 -->
|
<!-- Saved: 2018-09-24, 21:05:10 -->
|
||||||
<!-- Copyright (C) 2018 , -->
|
<!-- Copyright (C) 2018 , -->
|
||||||
<Project version="6.0">
|
<Project version="6.0">
|
||||||
<Language></Language>
|
<Language></Language>
|
||||||
|
@ -17,10 +17,14 @@
|
||||||
<Source>PluginManager/PluginStore/PluginStore.py</Source>
|
<Source>PluginManager/PluginStore/PluginStore.py</Source>
|
||||||
<Source>PluginManager/PluginStore/StoreModel.py</Source>
|
<Source>PluginManager/PluginStore/StoreModel.py</Source>
|
||||||
<Source>PluginManager/PluginStore/Ui_PluginStore.py</Source>
|
<Source>PluginManager/PluginStore/Ui_PluginStore.py</Source>
|
||||||
|
<Source>PluginManager/PluginStore/__init__.py</Source>
|
||||||
<Source>PluginManager/__init__.py</Source>
|
<Source>PluginManager/__init__.py</Source>
|
||||||
<Source>Plugins/PluginPage1.py</Source>
|
<Source>Plugins/PluginPage0_inMainLayout.py</Source>
|
||||||
<Source>Plugins/PluginPage2.py</Source>
|
<Source>Plugins/PluginPage1_addTab3.py</Source>
|
||||||
<Source>Plugins/Pluginmmm.py</Source>
|
<Source>Plugins/PluginPage1_addTab4.py</Source>
|
||||||
|
<Source>Plugins/PluginPage2_error.py</Source>
|
||||||
|
<Source>Plugins/PluginPage3_addAction1.py</Source>
|
||||||
|
<Source>Plugins/PluginPage3_addAction2.py</Source>
|
||||||
<Source>Plugins/__init__.py</Source>
|
<Source>Plugins/__init__.py</Source>
|
||||||
<Source>Plugins/page1/Ui_PluginPage1.py</Source>
|
<Source>Plugins/page1/Ui_PluginPage1.py</Source>
|
||||||
<Source>Plugins/page1/__init__.py</Source>
|
<Source>Plugins/page1/__init__.py</Source>
|
||||||
|
@ -38,6 +42,9 @@
|
||||||
<Form>Plugins/page2/PluginPage2.ui</Form>
|
<Form>Plugins/page2/PluginPage2.ui</Form>
|
||||||
<Form>main.ui</Form>
|
<Form>main.ui</Form>
|
||||||
</Forms>
|
</Forms>
|
||||||
|
<Others>
|
||||||
|
<Other>Documentation</Other>
|
||||||
|
</Others>
|
||||||
<MainScript>main.py</MainScript>
|
<MainScript>main.py</MainScript>
|
||||||
<Vcs>
|
<Vcs>
|
||||||
<VcsType>None</VcsType>
|
<VcsType>None</VcsType>
|
||||||
|
@ -60,4 +67,59 @@
|
||||||
<FiletypeAssociation pattern="README" type="OTHERS"/>
|
<FiletypeAssociation pattern="README" type="OTHERS"/>
|
||||||
<FiletypeAssociation pattern="README.*" type="OTHERS"/>
|
<FiletypeAssociation pattern="README.*" type="OTHERS"/>
|
||||||
</FiletypeAssociations>
|
</FiletypeAssociations>
|
||||||
|
<Documentation>
|
||||||
|
<DocumentationParams>
|
||||||
|
<dict>
|
||||||
|
<key>
|
||||||
|
<string>ERIC4DOC</string>
|
||||||
|
</key>
|
||||||
|
<value>
|
||||||
|
<dict>
|
||||||
|
<key>
|
||||||
|
<string>cssFile</string>
|
||||||
|
</key>
|
||||||
|
<value>
|
||||||
|
<string>%PYTHON%/eric6/CSSs/default.css</string>
|
||||||
|
</value>
|
||||||
|
<key>
|
||||||
|
<string>ignoreDirectories</string>
|
||||||
|
</key>
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<string>page1</string>
|
||||||
|
<string>page2</string>
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
<key>
|
||||||
|
<string>ignoreFilePatterns</string>
|
||||||
|
</key>
|
||||||
|
<value>
|
||||||
|
<list>
|
||||||
|
<string>Ui*.py</string>
|
||||||
|
<string>Plugins\\*Page*.py</string>
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
<key>
|
||||||
|
<string>outputDirectory</string>
|
||||||
|
</key>
|
||||||
|
<value>
|
||||||
|
<string>Documentation</string>
|
||||||
|
</value>
|
||||||
|
<key>
|
||||||
|
<string>qtHelpEnabled</string>
|
||||||
|
</key>
|
||||||
|
<value>
|
||||||
|
<bool>False</bool>
|
||||||
|
</value>
|
||||||
|
<key>
|
||||||
|
<string>useRecursion</string>
|
||||||
|
</key>
|
||||||
|
<value>
|
||||||
|
<bool>True</bool>
|
||||||
|
</value>
|
||||||
|
</dict>
|
||||||
|
</value>
|
||||||
|
</dict>
|
||||||
|
</DocumentationParams>
|
||||||
|
</Documentation>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Module implementing Form.
|
插件例子1.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -14,8 +14,6 @@ site: https://github.com/625781186 <br>
|
||||||
视频教程: https://space.bilibili.com/1863103/#/ <br>
|
视频教程: https://space.bilibili.com/1863103/#/ <br>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from PyQt5 import QtGui, QtWidgets, QtCore
|
from PyQt5 import QtGui, QtWidgets, QtCore
|
||||||
from PyQt5.QtCore import *
|
from PyQt5.QtCore import *
|
||||||
from PyQt5.QtGui import *
|
from PyQt5.QtGui import *
|
||||||
|
@ -27,6 +25,7 @@ try:
|
||||||
except:
|
except:
|
||||||
from page1.Ui_PluginPage1 import Ui_Form
|
from page1.Ui_PluginPage1 import Ui_Form
|
||||||
|
|
||||||
|
# 实例化类名, 必须
|
||||||
className = "Form"
|
className = "Form"
|
||||||
|
|
||||||
class Form(QWidget, Ui_Form):
|
class Form(QWidget, Ui_Form):
|
||||||
|
@ -35,10 +34,7 @@ class Form(QWidget, Ui_Form):
|
||||||
"""
|
"""
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
"""
|
"""
|
||||||
Constructor
|
|
||||||
|
|
||||||
@param parent reference to the parent widget
|
|
||||||
@type QWidget
|
|
||||||
"""
|
"""
|
||||||
super(Form, self).__init__(parent)
|
super(Form, self).__init__(parent)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
|
@ -46,8 +42,18 @@ class Form(QWidget, Ui_Form):
|
||||||
# layout = self.getParentLayout()
|
# layout = self.getParentLayout()
|
||||||
# layout.addWidget(self)
|
# layout.addWidget(self)
|
||||||
def getParentLayout(self):
|
def getParentLayout(self):
|
||||||
|
"""
|
||||||
|
布局函数,必须.
|
||||||
|
"""
|
||||||
return self.__mw.verticalLayout
|
return self.__mw.verticalLayout
|
||||||
|
|
||||||
|
def toInterface(self):
|
||||||
|
"""
|
||||||
|
插入到界面,必须
|
||||||
|
"""
|
||||||
|
layout = self.getParentLayout()
|
||||||
|
layout.addWidget(self)
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
print("die")
|
print("die")
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
Module implementing Form.
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
Created on 2018-09-18 <br>
|
|
||||||
description: $description$ <br>
|
|
||||||
author: 625781186@qq.com <br>
|
|
||||||
site: https://github.com/625781186 <br>
|
|
||||||
更多经典例子:https://github.com/892768447/PyQt <br>
|
|
||||||
课件: https://github.com/625781186/WoHowLearn_PyQt5 <br>
|
|
||||||
视频教程: https://space.bilibili.com/1863103/#/ <br>
|
|
||||||
"""
|
|
||||||
|
|
||||||
from PyQt5 import QtGui, QtWidgets, QtCore
|
|
||||||
from PyQt5.QtCore import *
|
|
||||||
from PyQt5.QtGui import *
|
|
||||||
from PyQt5.QtWidgets import *
|
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QWidget
|
|
||||||
|
|
||||||
from Plugin..Ui_PluginPage2 import Ui_Form
|
|
||||||
|
|
||||||
|
|
||||||
className = "Form"
|
|
||||||
|
|
||||||
class Form(QWidget, Ui_Form):
|
|
||||||
"""
|
|
||||||
Class documentation goes here.
|
|
||||||
"""
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
"""
|
|
||||||
Constructor
|
|
||||||
|
|
||||||
@param parent reference to the parent widget
|
|
||||||
@type QWidget
|
|
||||||
"""
|
|
||||||
super(Form, self).__init__(parent)
|
|
||||||
self.setupUi(self)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import sys
|
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
|
||||||
app.setStyle(QStyleFactory.create("Fusion"))
|
|
||||||
|
|
||||||
# 自定义CSS样式
|
|
||||||
# from BasePack.CommonHelper import CommonHelper
|
|
||||||
# styleFile = 'BasePack/style.css'
|
|
||||||
# qssStyle = CommonHelper.readQss( styleFile )
|
|
||||||
# framelessWindow.setStyleSheet( qssStyle )
|
|
||||||
|
|
||||||
# If you want to use this style, please pip install qdarkstyle.
|
|
||||||
# import qdarkstyle
|
|
||||||
# app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
|
|
||||||
|
|
||||||
ui = Form()
|
|
||||||
|
|
||||||
ui.show()
|
|
||||||
sys.exit(app.exec_())
|
|
|
@ -1,87 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
"""
|
|
||||||
Module implementing Form.
|
|
||||||
"""
|
|
||||||
|
|
||||||
"""
|
|
||||||
Created on 2018-09-18 <br>
|
|
||||||
description: $description$ <br>
|
|
||||||
author: 625781186@qq.com <br>
|
|
||||||
site: https://github.com/625781186 <br>
|
|
||||||
更多经典例子:https://github.com/892768447/PyQt <br>
|
|
||||||
课件: https://github.com/625781186/WoHowLearn_PyQt5 <br>
|
|
||||||
视频教程: https://space.bilibili.com/1863103/#/ <br>
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from PyQt5 import QtGui, QtWidgets, QtCore
|
|
||||||
from PyQt5.QtCore import *
|
|
||||||
from PyQt5.QtGui import *
|
|
||||||
from PyQt5.QtWidgets import *
|
|
||||||
|
|
||||||
from PyQt5.QtWidgets import QWidget
|
|
||||||
try:
|
|
||||||
from Ui_PluginPage1 import Ui_Form
|
|
||||||
except:
|
|
||||||
from page1.Ui_PluginPage1 import Ui_Form
|
|
||||||
|
|
||||||
className = "Form"
|
|
||||||
|
|
||||||
class Form(QWidget, Ui_Form):
|
|
||||||
"""
|
|
||||||
Class documentation goes here.
|
|
||||||
"""
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
"""
|
|
||||||
Constructor
|
|
||||||
|
|
||||||
@param parent reference to the parent widget
|
|
||||||
@type QWidget
|
|
||||||
"""
|
|
||||||
super(Form, self).__init__(parent)
|
|
||||||
self.setupUi(self)
|
|
||||||
self.__mw = parent
|
|
||||||
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
print("die")
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def on_pushButton_clicked(self):
|
|
||||||
|
|
||||||
print(15111)
|
|
||||||
pass
|
|
||||||
@pyqtSlot()
|
|
||||||
def on_pushButton_2_clicked(self):
|
|
||||||
|
|
||||||
print(222)
|
|
||||||
pass
|
|
||||||
@pyqtSlot()
|
|
||||||
def on_pushButton_3_clicked(self):
|
|
||||||
|
|
||||||
print(333)
|
|
||||||
pass
|
|
||||||
def getParentLayout(self):
|
|
||||||
return self.__mw.verticalLayout
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import sys
|
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
|
||||||
app.setStyle(QStyleFactory.create("Fusion"))
|
|
||||||
|
|
||||||
# 自定义CSS样式
|
|
||||||
# from BasePack.CommonHelper import CommonHelper
|
|
||||||
# styleFile = 'BasePack/style.css'
|
|
||||||
# qssStyle = CommonHelper.readQss( styleFile )
|
|
||||||
# framelessWindow.setStyleSheet( qssStyle )
|
|
||||||
|
|
||||||
# If you want to use this style, please pip install qdarkstyle.
|
|
||||||
# import qdarkstyle
|
|
||||||
# app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())
|
|
||||||
|
|
||||||
ui = Form()
|
|
||||||
|
|
||||||
ui.show()
|
|
||||||
sys.exit(app.exec_())
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
插件搜索目录.
|
||||||
|
"""
|
|
@ -0,0 +1,4 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
增删改查建json.
|
||||||
|
"""
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
"""
|
||||||
初始化json配置函数.
|
增删改查建json.
|
||||||
"""
|
"""
|
||||||
from PyQt5.QtWidgets import *
|
from PyQt5.QtWidgets import *
|
||||||
from PyQt5.QtWidgets import QMessageBox , QWidget , QApplication
|
from PyQt5.QtWidgets import QMessageBox , QWidget , QApplication
|
||||||
|
|
|
@ -11,7 +11,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
class Ui_MainWindow(object):
|
class Ui_MainWindow(object):
|
||||||
def setupUi(self, MainWindow):
|
def setupUi(self, MainWindow):
|
||||||
MainWindow.setObjectName("MainWindow")
|
MainWindow.setObjectName("MainWindow")
|
||||||
MainWindow.resize(510, 379)
|
MainWindow.resize(510, 378)
|
||||||
self.centralWidget = QtWidgets.QWidget(MainWindow)
|
self.centralWidget = QtWidgets.QWidget(MainWindow)
|
||||||
self.centralWidget.setObjectName("centralWidget")
|
self.centralWidget.setObjectName("centralWidget")
|
||||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralWidget)
|
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralWidget)
|
||||||
|
@ -39,11 +39,44 @@ class Ui_MainWindow(object):
|
||||||
self.menuBar.setObjectName("menuBar")
|
self.menuBar.setObjectName("menuBar")
|
||||||
self.menuFile = QtWidgets.QMenu(self.menuBar)
|
self.menuFile = QtWidgets.QMenu(self.menuBar)
|
||||||
self.menuFile.setObjectName("menuFile")
|
self.menuFile.setObjectName("menuFile")
|
||||||
|
self.menuOpen_Recent_Files = QtWidgets.QMenu(self.menuFile)
|
||||||
|
self.menuOpen_Recent_Files.setObjectName("menuOpen_Recent_Files")
|
||||||
|
self.menufile1 = QtWidgets.QMenu(self.menuOpen_Recent_Files)
|
||||||
|
self.menufile1.setObjectName("menufile1")
|
||||||
|
self.menufile11 = QtWidgets.QMenu(self.menufile1)
|
||||||
|
self.menufile11.setObjectName("menufile11")
|
||||||
self.menuEdit = QtWidgets.QMenu(self.menuBar)
|
self.menuEdit = QtWidgets.QMenu(self.menuBar)
|
||||||
self.menuEdit.setObjectName("menuEdit")
|
self.menuEdit.setObjectName("menuEdit")
|
||||||
self.menuView = QtWidgets.QMenu(self.menuBar)
|
self.menuView = QtWidgets.QMenu(self.menuBar)
|
||||||
self.menuView.setObjectName("menuView")
|
self.menuView.setObjectName("menuView")
|
||||||
MainWindow.setMenuBar(self.menuBar)
|
MainWindow.setMenuBar(self.menuBar)
|
||||||
|
self.actionadd1 = QtWidgets.QAction(MainWindow)
|
||||||
|
self.actionadd1.setObjectName("actionadd1")
|
||||||
|
self.actionsave = QtWidgets.QAction(MainWindow)
|
||||||
|
self.actionsave.setObjectName("actionsave")
|
||||||
|
self.actionOpen = QtWidgets.QAction(MainWindow)
|
||||||
|
self.actionOpen.setObjectName("actionOpen")
|
||||||
|
self.actionfile2 = QtWidgets.QAction(MainWindow)
|
||||||
|
self.actionfile2.setObjectName("actionfile2")
|
||||||
|
self.actionfile3 = QtWidgets.QAction(MainWindow)
|
||||||
|
self.actionfile3.setObjectName("actionfile3")
|
||||||
|
self.actionfile11 = QtWidgets.QAction(MainWindow)
|
||||||
|
self.actionfile11.setObjectName("actionfile11")
|
||||||
|
self.actionfile22 = QtWidgets.QAction(MainWindow)
|
||||||
|
self.actionfile22.setObjectName("actionfile22")
|
||||||
|
self.actionfile111 = QtWidgets.QAction(MainWindow)
|
||||||
|
self.actionfile111.setObjectName("actionfile111")
|
||||||
|
self.menufile11.addAction(self.actionfile111)
|
||||||
|
self.menufile1.addAction(self.menufile11.menuAction())
|
||||||
|
self.menufile1.addAction(self.actionfile22)
|
||||||
|
self.menuOpen_Recent_Files.addAction(self.menufile1.menuAction())
|
||||||
|
self.menuOpen_Recent_Files.addAction(self.actionfile2)
|
||||||
|
self.menuOpen_Recent_Files.addAction(self.actionfile3)
|
||||||
|
self.menuFile.addAction(self.actionadd1)
|
||||||
|
self.menuFile.addAction(self.actionsave)
|
||||||
|
self.menuFile.addAction(self.actionOpen)
|
||||||
|
self.menuFile.addSeparator()
|
||||||
|
self.menuFile.addAction(self.menuOpen_Recent_Files.menuAction())
|
||||||
self.menuBar.addAction(self.menuFile.menuAction())
|
self.menuBar.addAction(self.menuFile.menuAction())
|
||||||
self.menuBar.addAction(self.menuEdit.menuAction())
|
self.menuBar.addAction(self.menuEdit.menuAction())
|
||||||
self.menuBar.addAction(self.menuView.menuAction())
|
self.menuBar.addAction(self.menuView.menuAction())
|
||||||
|
@ -60,8 +93,19 @@ class Ui_MainWindow(object):
|
||||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1"))
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1"))
|
||||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2"))
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2"))
|
||||||
self.menuFile.setTitle(_translate("MainWindow", "File"))
|
self.menuFile.setTitle(_translate("MainWindow", "File"))
|
||||||
|
self.menuOpen_Recent_Files.setTitle(_translate("MainWindow", "Open Recent Files"))
|
||||||
|
self.menufile1.setTitle(_translate("MainWindow", "file1"))
|
||||||
|
self.menufile11.setTitle(_translate("MainWindow", "file11"))
|
||||||
self.menuEdit.setTitle(_translate("MainWindow", "Edit"))
|
self.menuEdit.setTitle(_translate("MainWindow", "Edit"))
|
||||||
self.menuView.setTitle(_translate("MainWindow", "View"))
|
self.menuView.setTitle(_translate("MainWindow", "View"))
|
||||||
|
self.actionadd1.setText(_translate("MainWindow", "New Window"))
|
||||||
|
self.actionsave.setText(_translate("MainWindow", "New"))
|
||||||
|
self.actionOpen.setText(_translate("MainWindow", "Open"))
|
||||||
|
self.actionfile2.setText(_translate("MainWindow", "file2"))
|
||||||
|
self.actionfile3.setText(_translate("MainWindow", "file3"))
|
||||||
|
self.actionfile11.setText(_translate("MainWindow", "file11"))
|
||||||
|
self.actionfile22.setText(_translate("MainWindow", "file22"))
|
||||||
|
self.actionfile111.setText(_translate("MainWindow", "file111"))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Module implementing MainWindow.
|
主函数入口.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -13,7 +13,7 @@ site: https://github.com/625781186 <br>
|
||||||
课件: https://github.com/625781186/WoHowLearn_PyQt5 <br>
|
课件: https://github.com/625781186/WoHowLearn_PyQt5 <br>
|
||||||
视频教程: https://space.bilibili.com/1863103/#/ <br>
|
视频教程: https://space.bilibili.com/1863103/#/ <br>
|
||||||
"""
|
"""
|
||||||
import os, time, imp, sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
from PyQt5 import QtGui, QtWidgets, QtCore
|
from PyQt5 import QtGui, QtWidgets, QtCore
|
||||||
|
@ -48,20 +48,21 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
||||||
"""
|
"""
|
||||||
print(sys.path)
|
print(sys.path)
|
||||||
pass
|
pass
|
||||||
|
def closeEvent(self, e):
|
||||||
|
self.pluginManager.dia.close()
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
app.setStyle(QStyleFactory.create("Fusion"))
|
app.setStyle(QStyleFactory.create("Fusion"))
|
||||||
|
|
||||||
# def excepthook(type, value, trace):
|
def excepthook(type, value, trace):
|
||||||
# try:
|
try:
|
||||||
# pass
|
pass
|
||||||
# except :
|
except :
|
||||||
# pass
|
pass
|
||||||
# sys.__excepthook__(type, value, trace)
|
sys.__excepthook__(type, value, trace)
|
||||||
|
|
||||||
# sys.excepthook = excepthook
|
sys.excepthook = excepthook
|
||||||
|
|
||||||
ui = MainWindow()
|
ui = MainWindow()
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>510</width>
|
<width>510</width>
|
||||||
<height>379</height>
|
<height>378</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -63,6 +63,32 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>File</string>
|
<string>File</string>
|
||||||
</property>
|
</property>
|
||||||
|
<widget class="QMenu" name="menuOpen_Recent_Files">
|
||||||
|
<property name="title">
|
||||||
|
<string>Open Recent Files</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menufile1">
|
||||||
|
<property name="title">
|
||||||
|
<string>file1</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QMenu" name="menufile11">
|
||||||
|
<property name="title">
|
||||||
|
<string>file11</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionfile111"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menufile11"/>
|
||||||
|
<addaction name="actionfile22"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menufile1"/>
|
||||||
|
<addaction name="actionfile2"/>
|
||||||
|
<addaction name="actionfile3"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="actionadd1"/>
|
||||||
|
<addaction name="actionsave"/>
|
||||||
|
<addaction name="actionOpen"/>
|
||||||
|
<addaction name="separator"/>
|
||||||
|
<addaction name="menuOpen_Recent_Files"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menuEdit">
|
<widget class="QMenu" name="menuEdit">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
|
@ -78,6 +104,46 @@
|
||||||
<addaction name="menuEdit"/>
|
<addaction name="menuEdit"/>
|
||||||
<addaction name="menuView"/>
|
<addaction name="menuView"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
<action name="actionadd1">
|
||||||
|
<property name="text">
|
||||||
|
<string>New Window</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionsave">
|
||||||
|
<property name="text">
|
||||||
|
<string>New</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionOpen">
|
||||||
|
<property name="text">
|
||||||
|
<string>Open</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionfile2">
|
||||||
|
<property name="text">
|
||||||
|
<string>file2</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionfile3">
|
||||||
|
<property name="text">
|
||||||
|
<string>file3</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionfile11">
|
||||||
|
<property name="text">
|
||||||
|
<string>file11</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionfile22">
|
||||||
|
<property name="text">
|
||||||
|
<string>file22</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionfile111">
|
||||||
|
<property name="text">
|
||||||
|
<string>file111</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
Loading…
Reference in a new issue