跟着cherno手搓游戏引擎【10】使用glm窗口特性

修改ImGui层架构:

创建:

ImGuiBuild.cpp:引入ImGui

#include"ytpch.h"
#define IMGUI_IMPL_OPENGL_LOADER_GLAD//opengl的头文件需要的定义,说明使用的是gald
#include "backends/imgui_impl_opengl3.cpp"
#include "backends/imgui_impl_glfw.cpp"

Layer.h:加入GuiRender方法,每次渲染Gui都会调用

#pragma once
#include"YOTO/Core.h"
#include"YOTO/Event/Event.h"
namespace YOTO {class YOTO_API Layer{public:Layer(const std::string& name = "Layer");virtual ~Layer();virtual void OnAttach(){}virtual void OnDetach() {}virtual void OnUpdate() {}virtual void OnImGuiRender() {}// 每层都可以拥有自己的UI窗口virtual void OnEvent(Event& event) {}inline const std::string& GetName() const { return m_DebugName; }protected:std::string m_DebugName;};}

ImGuiLayer.h:删除冗余部分,仅留下加入,删除,和Render方法,添加Begine和End,用于每次刷新UI的配置和删除UI。

#pragma once
#include"YOTO/Layer.h"
#include"YOTO/Event/KeyEvent.h"
#include"YOTO/Event/MouseEvent.h"
#include"YOTO/Event/ApplicationEvent.h"
namespace YOTO {class YOTO_API ImGuiLayer:public Layer{public:ImGuiLayer();~ImGuiLayer();virtual void OnAttach()override;virtual void OnDetach()override;virtual void OnImGuiRender()override; void Begin();void End();private:float m_Time = 0.0f;};
}

ImGuiLayer.cpp:删除原来的Update,把配置、绘制UI的代码、渲染分离

#include"ytpch.h"
#include"ImGuiLayer.h"#include"YOTO/Application.h"#include<GLFW/glfw3.h>
#include<glad/glad.h>#define IMGUI_IMPL_API
#include "backends/imgui_impl_glfw.h"
#include "backends/imgui_impl_opengl3.h"
namespace YOTO {ImGuiLayer::ImGuiLayer():Layer("ImGuiLayer") {}ImGuiLayer::~ImGuiLayer() {}void ImGuiLayer::OnAttach(){// 不需要手动写ImGui的键值对应GLFW的键值、ImGui接收GLFW窗口事件,ImGui自动完成// 设置Gui配置IMGUI_CHECKVERSION();ImGui::CreateContext();ImGuiIO& io = ImGui::GetIO(); (void)io;io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;       // 启用键盘控制//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      //启用手柄控制io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;           // 启用自动布局io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;         //启用多视窗/平台视窗(也就是能走出Opengl绘制的框子)//io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoTaskBarIcons;//io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoMerge;// 设置Gui配置样式ImGui::StyleColorsDark();//ImGui::StyleColorsClassic();// 当viewport被启用时,我们调整windowwround /WindowBg,使平台窗口看起来与常规窗口相同。ImGuiStyle& style = ImGui::GetStyle();if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable){style.WindowRounding = 0.0f;style.Colors[ImGuiCol_WindowBg].w = 1.0f;}Application& app = Application::Get();GLFWwindow* window = static_cast<GLFWwindow*>(app.GetWindow().GetNativeWindow());//设置平台/渲染器绑定ImGui_ImplGlfw_InitForOpenGL(window, true);ImGui_ImplOpenGL3_Init("#version 410");}void ImGuiLayer::OnDetach(){ImGui_ImplOpenGL3_Shutdown();ImGui_ImplGlfw_Shutdown();ImGui::DestroyContext();}void ImGuiLayer::OnImGuiRender(){static bool show = true;ImGui::ShowDemoWindow(&show);// 当前OnImGuiRender层显示DemoUI窗口}void ImGuiLayer::Begin(){ImGui_ImplOpenGL3_NewFrame();ImGui_ImplGlfw_NewFrame();ImGui::NewFrame();}void ImGuiLayer::End(){ImGuiIO& io = ImGui::GetIO();Application& app = Application::Get();io.DisplaySize = ImVec2(app.GetWindow().GetWidth(), app.GetWindow().GetHeight());// RenderingImGui::Render();ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());//如果启动启用多视窗/平台视窗if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable){GLFWwindow* backup_current_context = glfwGetCurrentContext();ImGui::UpdatePlatformWindows();ImGui::RenderPlatformWindowsDefault();glfwMakeContextCurrent(backup_current_context);}}}

LayerStack.h:修改m_LayerInsertIndex:

#pragma once
#include"Layer.h"namespace YOTO {class  YOTO_API LayerStack{public:LayerStack();~LayerStack();void PushLayer(Layer* layer);void PushOverlay(Layer* layer);void PopLayer(Layer* layer);void PopOverlay(Layer* layer);std::vector<Layer*>::iterator begin() { return m_Layers.begin(); }std::vector<Layer*>::iterator end() { return m_Layers.end(); }private:std::vector<Layer*>m_Layers;unsigned int m_LayerInsertIndex=0;};}

LayerStack.cpp: 修改PushLayer:

#include "ytpch.h"
#include "LayerStack.h"
namespace YOTO {LayerStack::LayerStack() {}LayerStack::~LayerStack() {for (Layer* layer : m_Layers)delete layer;}//普通push在队列最左(查找时候性能更优)void LayerStack::PushLayer(Layer* layer) {// emplace在vector容器指定位置之前插入一个新的元素。返回插入元素的位置// 插入 1 2 3,vector是 3 2 1m_Layers.emplace(m_Layers.begin()+ m_LayerInsertIndex, layer);m_LayerInsertIndex++;}//在最右插入void LayerStack::PushOverlay(Layer* overlay) {//m_LayerInsert = m_Layers.begin();//如果报错,则把这个注释取消m_Layers.emplace_back(overlay);}//查找void LayerStack::PopLayer(Layer* layer) {auto it = std::find(m_Layers.begin(), m_Layers.end(), layer);if (it != m_Layers.end()) {m_Layers.erase(it);m_LayerInsertIndex--;	// 指向Begin}}void LayerStack::PopOverlay(Layer* overlay) {auto it = std::find(m_Layers.begin(), m_Layers.end(), overlay);if (it != m_Layers.end())m_Layers.erase(it);}
}

Application.h:在APP中添加Gui层,无需在Sandbox中手动添加:

#pragma once
#include"Core.h"
#include"Event/Event.h"
#include"Event/ApplicationEvent.h"
#include "YOTO/Window.h"
#include"YOTO/LayerStack.h"
#include"YOTO/ImGui/ImGuiLayer.h"
namespace YOTO {class YOTO_API Application{public:Application();virtual ~Application();void Run();void OnEvent(Event &e);void PushLayer(Layer* layer);void PushOverlay(Layer* layer);inline static Application& Get() {return * s_Instance;}inline Window& GetWindow() { return *m_Window; }private:bool  OnWindowClosed(WindowCloseEvent& e);std::unique_ptr<Window>  m_Window;ImGuiLayer *  m_ImGuiLayer;bool m_Running = true;LayerStack m_LayerStack;static Application* s_Instance;};//在客户端定义Application* CreateApplication();
}

Application.cpp:在构造函数中newImGuiLayer然后Push到最后

#include"ytpch.h"
#include "Application.h"#include"Log.h"
#include<glad/glad.h>
#include"Input.h"namespace YOTO {
#define BIND_EVENT_FN(x) std::bind(&x, this, std::placeholders::_1)Application* Application::s_Instance = nullptr;Application::Application() {YT_CORE_ASSERT(!s_Instance, "Application需要为空!")s_Instance = this;//智能指针m_Window = std::unique_ptr<Window>(Window::Creat());//设置回调函数m_Window->SetEventCallback(BIND_EVENT_FN(Application::OnEvent));//new一个Layer,放在最后层进行渲染m_ImGuiLayer = new ImGuiLayer();PushOverlay(m_ImGuiLayer);  //unsigned int id;//glGenBuffers(1, &id);}Application::~Application() {}/// <summary>/// 所有的Window事件都会在这触发,作为参数e/// </summary>/// <param name="e"></param>void Application::OnEvent(Event& e) {//根据事件类型绑定对应事件EventDispatcher dispatcher(e);dispatcher.Dispatch<WindowCloseEvent>(BIND_EVENT_FN(Application::OnWindowClosed));//输出事件信息YT_CORE_INFO("Application:{0}",e);for (auto it = m_LayerStack.end(); it != m_LayerStack.begin();) {(*--it)->OnEvent(e);if (e.m_Handled)break;}}bool Application::OnWindowClosed(WindowCloseEvent& e) {m_Running = false;return true;}void Application::Run() {WindowResizeEvent e(1280, 720);if (e.IsInCategory(EventCategoryApplication)) {YT_CORE_TRACE(e);}if (e.IsInCategory(EventCategoryInput)) {YT_CORE_ERROR(e);}while (m_Running){glClearColor(1,0,1,1);glClear(GL_COLOR_BUFFER_BIT);for (Layer* layer : m_LayerStack) {layer->OnUpdate();}//将ImGui的刷新放到APP中,与Update分开m_ImGuiLayer->Begin();for (Layer* layer : m_LayerStack) {layer->OnImGuiRender();}m_ImGuiLayer->End();m_Window->OnUpdate();}}void Application::PushLayer(Layer* layer) {m_LayerStack.PushLayer(layer);layer->OnAttach();}void Application::PushOverlay(Layer* layer) {m_LayerStack.PushOverlay(layer);layer->OnAttach();}
}

SandboxApp.cpp:把PushImgGui的哪行代码删掉:

#include<YOTO.h>
#include "imgui/imgui.h"
#include<stdio.h>
//#include <glm/vec3.hpp> // glm::vec3
//#include <glm/vec4.hpp> // glm::vec4
//#include <glm/mat4x4.hpp> // glm::mat4
//#include <glm/gtc/matrix_transform.hpp> // glm::translate, glm::rotate, glm::scale, glm::perspective
//glm::mat4 camera(float Translate, glm::vec2 const& Rotate)
//{
//	glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.f);
//	glm::mat4 View = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Translate));
//	View = glm::rotate(View, Rotate.y, glm::vec3(-1.0f, 0.0f, 0.0f));
//	View = glm::rotate(View, Rotate.x, glm::vec3(0.0f, 1.0f, 0.0f));
//	glm::mat4 Model = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f));
//	return Projection * View * Model;
//}class ExampleLayer:public YOTO::Layer
{
public:ExampleLayer():Layer("Example") {//auto cam=camera(5.0f,{0.5f,0.5f});}void OnImGuiRender() override {ImGui::Begin("Test");ImGui::Text("Test");ImGui::End();}void OnUpdate()override {//YT_CLIENT_INFO("测试update");if (YOTO::Input::IsKeyPressed(YT_KEY_TAB)) {YT_CLIENT_INFO("ExampleLayerOnUpdate:TAB按下了");}}void OnEvent(YOTO::Event& event)override {if (event.GetEventType() == YOTO::EventType::KeyPressed) {YOTO:: KeyPressedEvent& e = (YOTO::KeyPressedEvent&)event;YT_CLIENT_TRACE("ExampleLayer:{0}",(char)e.GetKeyCode());if (e.GetKeyCode()==YT_KEY_TAB) {YT_CLIENT_INFO("ExampleLayerOnEvent:TAB按下了");}}//YT_CLIENT_TRACE("SandBoxApp:测试event{0}", event);}private:};class Sandbox:public YOTO::Application
{
public:Sandbox() {PushLayer(new ExampleLayer());//PushLayer(new YOTO::ImGuiLayer());}~Sandbox() {}private:};YOTO::Application* YOTO::CreateApplication() {printf("helloworld");return new Sandbox();
}

作业:

src下的premake5.lua:修改sandbox的includedirs加入"YOTOEngine/vendor"

workspace "YOTOEngine"		-- sln文件名architecture "x64"	configurations{"Debug","Release","Dist"}
startproject "Sandbox"
-- https://github.com/premake/premake-core/wiki/Tokens#value-tokens
-- 组成输出目录:Debug-windows-x86_64
outputdir = "%{cfg.buildcfg}-%{cfg.system}-%{cfg.architecture}"
-- 包含相对解决方案的目录
IncludeDir={}
IncludeDir["GLFW"]="YOTOEngine/vendor/GLFW/include"
IncludeDir["Glad"]="YOTOEngine/vendor/Glad/include"
IncludeDir["ImGui"] ="YOTOEngine/vendor/imgui"
IncludeDir["glm"] ="YOTOEngine/vendor/glm"
--项目中包含某包
include "YOTOEngine/vendor/GLFW"
include "YOTOEngine/vendor/Glad"
include "YOTOEngine/vendor/imgui"project "YOTOEngine"		--YOTOEngine项目location "YOTOEngine"--在sln所属文件夹下的YOTOEngine文件夹kind "SharedLib"--dll动态库language "C++"targetdir ("bin/" .. outputdir .. "/%{prj.name}") -- 输出目录objdir ("bin-int/" .. outputdir .. "/%{prj.name}")-- 中间目录staticruntime "Off"pchheader "ytpch.h"pchsource "YOTOEngine/src/ytpch.cpp"-- 包含的所有h和cpp文件files{"%{prj.name}/src/**.h","%{prj.name}/src/**.cpp","%{prj.name}/vendor/glm/glm/**.hpp","%{prj.name}/vendor/glm/glm/**.inl"}-- 包含目录includedirs{"%{prj.name}/src","%{prj.name}/vendor/spdlog-1.x/include","%{IncludeDir.GLFW}","%{IncludeDir.Glad}","%{IncludeDir.ImGui}","%{IncludeDir.glm}"}links{"GLFW",-- GLFW.lib库链接到YOTOEngine项目中"Glad",-- Glad.lib库链接到YOTOEngine项目中"ImGui",-- ImGui.lib库链接到YOTOEngine项目中"opengl32.lib"}-- 如果是window系统filter "system:windows"cppdialect "C++17"-- On:代码生成的运行库选项是MTD,静态链接MSVCRT.lib库;-- Off:代码生成的运行库选项是MDD,动态链接MSVCRT.dll库;打包后的exe放到另一台电脑上若无这个dll会报错systemversion "latest"	-- windowSDK版本-- 预处理器定义defines{"YT_PLATFORM_WINDOWS","YT_BUILD_DLL",-- "YT_ENABLE_ASSERTS","GLFW_INCLUDE_NONE"-- 让GLFW不包含OpenGL}-- 编译好后移动Hazel.dll文件到Sandbox文件夹下postbuildcommands{("{COPY} %{cfg.buildtarget.relpath} ../bin/" .. outputdir .. "/Sandbox")}-- 不同配置下的预定义不同filter "configurations:Debug"defines "YT_DEBUG"runtime "Debug"symbols "On"filter "configurations:Release"defines "YT_RELEASE"runtime "Release"optimize "On"filter "configurations:Dist"defines "YT_DIST"runtime "Release"optimize "On"project "Sandbox"location "Sandbox"kind "ConsoleApp"language "C++"staticruntime "Off"targetdir ("bin/" .. outputdir .. "/%{prj.name}")objdir ("bin-int/" .. outputdir .. "/%{prj.name}")files{"%{prj.name}/src/**.h","%{prj.name}/src/**.cpp"}-- 同样包含spdlog头文件includedirs{"YOTOEngine/vendor/spdlog-1.x/include","YOTOEngine/src","YOTOEngine/vendor","%{IncludeDir.glm}"}-- 引用YOTOEnginelinks{"YOTOEngine","GLFW","opengl32.lib"}filter "system:windows"cppdialect "C++17"systemversion "latest"defines{"YT_PLATFORM_WINDOWS"}filter "configurations:Debug"defines "YT_DEBUG"runtime "Debug"symbols "On"filter "configurations:Release"defines "YT_RELEASE"runtime "Release"optimize "On"filter "configurations:Dist"defines "YT_DIST"runtime "Release"optimize "On"

 vendor/ImGui的premake5.la添加    defines { "IMGUI_API=__declspec(dllexport)" }

project "ImGui"kind "StaticLib"language "C++"staticruntime "off"targetdir ("bin/" .. outputdir .. "/%{prj.name}")objdir ("bin-int/" .. outputdir .. "/%{prj.name}")defines { "IMGUI_API=__declspec(dllexport)" }files{"imconfig.h","imgui.h","imgui.cpp","imgui_draw.cpp","imgui_internal.h","imgui_tables.cpp","imgui_widgets.cpp","imstb_rectpack.h","imstb_textedit.h","imstb_truetype.h","imgui_demo.cpp"}filter "system:windows"systemversion "latest"cppdialect "C++17"filter "system:linux"pic "On"systemversion "latest"cppdialect "C++17"filter "configurations:Debug"runtime "Debug"symbols "on"filter "configurations:Release"runtime "Release"optimize "on"filter "configurations:Dist"runtime "Release"optimize "on"symbols "off"

测试:

点dockspace

点出来几个窗口随便摆摆:

 能拖出去:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/653045.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

03_Opencv简单实例演示效果和基本介绍

视频处理 视频分解图片 在后面我们要学习的机器学习中,我们需要大量的图片训练样本,这些图片训练样本如果我们全都使用相机拍照的方式去获取的话,工作量会非常巨大, 通常的做法是我们通过录制视频,然后提取视频中的每一帧即可! 接下来,我们就来学习如何从视频中获取信息 ubun…

c#之构值类型和引用类型

值类型:(整数/bool/struct/char/小数) 引用类型:(string/ 数组 / 自定义的类 / 内置的类) 值类型只需要一段单独的内存,用于存储实际的数据 引用类型需要两段内存(第一段存储实际的数据,他总是位于 堆中第二段是一个引用,指向数据在堆中的存放位置) 当使用引用类型赋值的时…

C++:类 的简单介绍(一)

目录 类的引用&#xff1a; 类的定义&#xff1a; 类的两种定义方式&#xff1a; 成员变量命名规则的建议&#xff1a; 类的访问限定符及封装&#xff1a; 访问限定符 【访问限定符说明】 封装 class与struct的区别&#xff1a; 类的作用域&#xff1a; 类的实例化…

嵌入式——直接存储器存取(DMA)补充

目录 一、认识 DMA 二、DMA结构 1. DMA请求 2. 通道DMA 补&#xff1a;通道配置过程。 3. 仲裁器 三、DMA数据配置 1. 从哪里来&#xff0c;到哪里去 &#xff08;1&#xff09;从外设到存储器 &#xff08;2&#xff09;从存储器到外设 &#xff08;3&#xff09;从…

React 组件生命周期-概述、生命周期钩子函数 - 挂载时、生命周期钩子函数 - 更新时、生命周期钩子函数 - 卸载时

React 组件生命周期-概述 学习目标&#xff1a; 能够说出组件的生命周期一共几个阶段 组件的生命周期是指组件从被创建到挂在到页面中运行&#xff0c;在到组件不用时卸载组件 注意&#xff1a;只有类组件才有生命周期&#xff0c;函数组件没有生命周期(类组件需要实例化&…

LeetCode344反转字符串(java实现)

今天我们来分享的题目是leetcode344反转字符串。题目描述如下&#xff1a; 我们观察题目发现&#xff0c;题目要求使用O(1)的空间解决这一问题。那么我们就不能进行使用开辟新的数组进行反转了。 解题思路&#xff1a;那么该题的我得思路是使用双指针的方法进行题解&#xff0…

2024獬豸杯

2024.1.28上午9-12时&#xff0c;返乡大学生边帮姐带娃边做&#xff0c;有几题没交上 解压密码&#xff1a;都考100分 手机备份包 手机基本信息 1、IOS手机备份包是什么时候开始备份的。&#xff08;标准格式&#xff1a;2024-01-20.12:12:12) 2024-01-15.14.19.44 2、请分…

Docker 安装与基本操作

目录 一、Docker 概述 1、Docker 简述 2、Docker 的优势 3、Docker与虚拟机的区别 4、Docker 的核心概念 1&#xff09;镜像 2&#xff09;容器 3&#xff09;仓库 二、Docker 安装 1、命令&#xff1a; 2、实操&#xff1a; 三、Docker 镜像操作 1、命令&#xff1…

centos7 挂载windows共享文件夹报错提示写保护

centos7挂载windows共享时&#xff0c;提示被共享的位置写保护&#xff0c;只能以只读方式挂载&#xff0c;紧接着就是以只读方式挂载失败 原因是组件少装了 yum install cifs-utils 安装完后&#xff0c;正常挂载使用。 下载离线安装包 下载离线包下载工具 下载离线安装包…

SpringBoot系列之MybatisPlus实现分组查询

SpringBoot系列之MybatisPlus实现分组查询 我之前博主曾记写过一篇介绍SpringBoot2.0项目怎么集成MybatisPlus的教程&#xff0c;不过之前的博客只是介绍了怎么集成&#xff0c;并没有做详细的描述各种业务场景&#xff0c;本篇博客是对之前博客的补充&#xff0c;介绍在mybat…

2024/1/27 备战蓝桥杯 1-1

目录 求和 0求和 - 蓝桥云课 (lanqiao.cn) 成绩分析 0成绩分析 - 蓝桥云课 (lanqiao.cn) 合法日期 0合法日期 - 蓝桥云课 (lanqiao.cn) 时间加法 0时间加法 - 蓝桥云课 (lanqiao.cn) 扫雷 0扫雷 - 蓝桥云课 (lanqiao.cn) 大写 0大写 - 蓝桥云课 (lanqiao.cn) 标题…

【SpringSpringBoot】概述

Spring&SpringBoot专题 【注】&#xff1a; 本专题围绕框架核心概念展开&#xff0c;渐进式深入总结学习、面试、开发经验&#xff0c;集中整理便于回顾 持续补充与施工中~~~~ 1.发展史 2.基本架构 Spring框架的基本架构是一个分层架构&#xff0c;包括多个模块&#x…

2024三掌柜赠书活动第六期:人人都离不开的算法——图解算法应用

目录 前言算法概念图解算法应用算法的价值和挑战关于《人人都离不开的算法——图解算法应用》编辑推荐内容简介作者简介图书目录书中前言/序言书摘插画《人人都离不开的算法——图解算法应用》全书速览结束语 前言 作为开发者想必都知道&#xff0c;算法是现代社会中无处不在…

day33_js

今日内容 0 复习昨日 1 JS概述 2 JS的引入方式 3 JS语法 3.1 变量 3.2 基本数据类型 3.3 引用类型 3.4 数组类型 3.5 日期类型 3.6 运算符(算术运算,逻辑,关系运算,三目运算) 3.7 分支 3.8 循环 3.9 函数(重点) 3 常见弹窗函数 alter,confirm,prompt 0 复习昨日 1 盒子模型 对d…

兄弟MFC-8515DN黑白激光多功能一体机硒鼓及粉盒清零方法

耗材信息&#xff1a; 硒鼓DR-3350&#xff1a;约30000页&#xff1b; 墨粉盒TN-3335&#xff1a;约3000页【A4纸5%覆盖率】&#xff1b; 高容量墨粉盒TN-3385&#xff1a;约8000页【A4纸5%覆盖率】&#xff1b; 超高容量墨粉盒TN-3395&#xff1a;约12000页【A4纸5%覆盖率】&a…

php项目下微信小程序对接实战问题与解决方案

一.实战问题与方案总结 1.SQL查询条件是一组数&#xff0c;传参却是一个字符串导致报错&#xff0c;如下 SQLSTATE[HY093]: Invalid parameter number (SQL: select count(*) as aggregate from car_video where province_id in (1492) and city_id in (1493) and county_id …

个体诊所电子处方系统设计,社区门诊处方开单管理系统软件教程

个体诊所电子处方系统设计&#xff0c;社区门诊处方开单管理系统软件教程 一、前言 以下软件程序操作教程以 佳易王诊所电子处方管理系统软件V17.3为例说明 如图&#xff0c;在基本信息设置里&#xff0c;可以设置处方配方模板&#xff0c;这样在开电子处方的时候可以一键导入…

计算机提示缺失dll文件怎么办?那种dll解决方法更值得推荐

当在运行游戏&#xff0c;软件程序的过程中遇到“找不到dll”的情况时&#xff0c;这实际上意味着系统或应用程序无法定位并加载必要的动态链接库文件&#xff08;DLL&#xff09;&#xff0c;从而无法顺利完成预期的功能调用和执行流程。这种问题的发生可能会引发一系列严重后…

Selenium + Django + Echarts 实现亚马逊商品数据可视化爬虫项目

最近完成了1个爬虫项目&#xff0c;记录一下自己的心得。 项目功能简介 根据用户输入商品名称、类别名称&#xff0c;使用Selenium, BS4等技术每天定时抓取亚马逊商品数据&#xff0c;使用Pandas进行数据清洗后保存在MySql数据库中. 使用Django提供用户端功能&#xff0c;显…

【electron】安装网络问题处理

目录 场景排查问题排查结论electron 安装失败解决方案 新的问题electron-builder 打包失败处理 场景 在mac上使用electron进行代码开发的时候&#xff0c;无法正常下载与electron、electron-builder相关的依赖 排查问题 是不是因为没有翻墙导致资源无法下载是不是没有设置正…