
Windows11关于利用Qt和live2d-py自制重返未来1999的桌面动态壁纸前言前期准备1、准备一个工程文件夹按照以下格式存放文件与文件夹2、安装python 3.113、准备额外依赖项python源码建议看一遍源码再复制一些其他问题角色资源模型有白色方块模型脸部有黑色的拼接缝隙其它关于更新其他没什么了大家中秋快乐前言这只是基础版有很多没更新前期准备1、准备一个工程文件夹按照以下格式存放文件与文件夹project/ ├── Model/ │ └── 你的角色代码1/ │ ├── expressions/ │ │ ├── ... │ │ ├── 面部json文件1.json │ │ └── 面部json文件2.json │ ├── motions/ │ │ ├── ... │ │ ├── 动作json文件1.json │ │ └── 动作json文件2.json │ ├── textures/ │ │ ├── ... │ │ ├── png纹理图1.png │ │ └── png纹理图2.png │ ├── 角色1.moc3 │ └── 角色1.model3.json └── 源码.py2、安装python 3.113、准备额外依赖项有条件的在虚拟环境里安装pip install pyside6 live2d-pypython源码建议看一遍源码再复制importos.pathimportsysfromPySide6.QtGuiimportQSurfaceFormatfromPySide6.QtWidgetsimportQApplication,QWidget,QMainWindowfromPySide6.QtOpenGLWidgetsimportQOpenGLWidgetfromPySide6.QtCoreimportQTimer,Qt,Signalimportlive2d.v3asl2dimportwin32conimportwin32guiimportwin32apiimporttimeimportpathlibimportjsonclassmotionJson:def__init__(self,json_path):withopen(json_path,r)asf:textf.read()self.Jsonjson.loads(text)self.motionself.Json[FileReferences][Motions]expressionsself.Json[FileReferences][Expressions]self.expressions{}forexpinexpressions:self.expressions[exp[Name]]exp[File]self.motion2num{}self.num2motion[]self.expression2num{}self.num2expression[]i0fornameinself.motion.keys():self.motion2num[name]i self.num2motion.append(name)i1i0fornameinself.expressions.keys():self.expression2num[name]i self.num2expression.append(name)i1classLive2DWidget(QOpenGLWidget):modelLoadedSignal()def__init__(self,model_path,role_name):super().__init__()self.modelNoneself.role_namerole_name self.timerQTimer(self)self.timer.timeout.connect(self.update)self.timer.start(16)self.model_pathmodel_path self.JsonmotionJson(self.model_path/self.role_name.model3.json)definitializeGL(self):l2d.init()l2d.glInit()model_path_self.model_path/self.role_name.model3.jsonifos.path.exists(model_path_):self.modell2d.LAppModel()self.model.LoadModelJson(model_path_)self.model.Resize(self.width(),self.height())self.modelLoaded.emit()else:print(f模型文件未找到:{model_path_})defpaintGL(self):ifself.model:l2d.clearBuffer()self.model.Update()# 缩放1.0 默认0.8 缩小到 80%1.2 放大到 120%self.model.SetScale(1.3)# 水平正数向右负数向左# 垂直正数向上负数向下self.model.SetOffset(-0.7,-1.2)ifself.model.IsMotionFinished():self.model.StartMotion(body,self.Json.motion2num[b_idle],l2d.MotionPriority.NORMAL)self.model.Draw()defresizeGL(self,w,h):窗口大小改变时调整模型的显示大小ifself.model:self.model.Resize(self.width(),self.height())defmotion(self):foriinrange(len(self.Json.motion)):motionself.model_path/self.Json.motion[self.Json.num2motion[i]][0][File]self.model.LoadExtraMotion(motionJsonPathmotion,groupbody)self.model.StartMotion(body,self.Json.motion2num[b_idle],l2d.MotionPriority.NORMAL)defexpressions(self):foriinrange(len(self.Json.expressions)):expself.model_path/self.Json.expressions[self.Json.num2expression[i]]self.model.LoadExtraExpression(self.Json.num2expression[i],filePathexp)self.model.SetExpression(e_idle)classl2d_windows(QMainWindow):def__init__(self,model_path,role_name,x0,y0,w3456,h1920):super().__init__()self.setGeometry(x,y,w,h)self.setWindowFlags(Qt.FramelessWindowHint)# 允许窗口透明self.setAttribute(Qt.WA_TranslucentBackground)self.l2d_widgetLive2DWidget(model_path,role_name)self.setCentralWidget(self.l2d_widget)self.l2d_widget.modelLoaded.connect(self.f_connect)deff_connect(self):self.l2d_widget.motion()self.l2d_widget.expressions()defmake_me_wallpaper(hwnd,x0,y0,screen_wwin32api.GetSystemMetrics(win32con.SM_CXSCREEN),screen_hwin32api.GetSystemMetrics(win32con.SM_CYSCREEN)):# 1. 先把窗口改成无边框WS_CHILDstylewin32gui.GetWindowLong(hwnd,win32con.GWL_STYLE)stylestyle~win32con.WS_OVERLAPPEDWINDOW|win32con.WS_CHILD win32gui.SetWindowLong(hwnd,win32con.GWL_STYLE,style)exstylewin32gui.GetWindowLong(hwnd,win32con.GWL_EXSTYLE)exstyleexstyle|win32con.WS_EX_LAYERED win32gui.SetWindowLong(hwnd,win32con.GWL_EXSTYLE,exstyle)# 2. 找到 Progmanprogmanwin32gui.FindWindow(Progman,None)ifnotprogman:returnFalse# 3. 发消息让它生成 WorkerWwin32gui.SendMessage(progman,0x052C,0,0)time.sleep(0.3)# 4. 枚举所有 WorkerWworkerw_list[]defenum_cb(h,_):ifwin32gui.GetClassName(h)WorkerW:workerw_list.append(h)returnTruewin32gui.EnumChildWindows(progman,enum_cb,0)ifnotworkerw_list:returnFalsetarget_workerwworkerw_list[-1]win32gui.SetParent(hwnd,target_workerw)# 5. 全屏win32gui.SetWindowPos(hwnd,None,x,y,screen_w,screen_h,win32con.SWP_NOZORDER|win32con.SWP_NOACTIVATE)# 确保窗口显示win32gui.ShowWindow(int(hwnd),win32con.SW_SHOW)returnTrueif__name____main__:appQApplication([])rootl2d_windows(Model/315502,315502)# 这里将315502替换为你的角色代码角色代码就是你的moc3文件名hwndroot.winId()ifmake_me_wallpaper(hwnd,screen_w3456,screen_h1920):# screen_w与screen_h替换为你电脑屏幕的实际分辨率print(Successfully set the window as wallpaper.)else:print(Failed to set the window as wallpaper.)root.show()sys.exit(app.exec())需要改模型的大小与位置在 Live2DWidget.paintGL() 里面修改该代码的详细教程与注意事项以后有空的时候再出一些其他问题角色资源可以在github上找找我记得有位大佬上传过1999的全套live2d资源也可以通过https://uttu.merui.net/ 这个网站看看这个网站有模型但没办法直接下只能通过其他办法获取该网址的模型而且通过该网站获取的纹理图是webp格式的需要转为png格式有空的时候会出教程模型有白色方块这个是moc3文件中存在一系列名为bone的网格有bone、bone1、bone2…需要调整这些网格的透明度让其完全透明隐藏有会live2d的大佬应该会用Cubism调整这些网格吧这方面我不太清楚有空的时候会出用python调整的代码模型脸部有黑色的拼接缝隙该问题主要是因为纹理图各个纹理的边缘有黑色的描边这个会在出角色资源教程时给出我的一个解决方案其它关于更新闲暇的时候更新一下交互什么的吧说不定能添加一些好玩的功能其他没什么了大家中秋快乐