Python实现图片浏览器
Python实现图片浏览器
支持浏览多种常见图片格式:JPG, JPEG, PNG, GIF, BMP, TIFF, WEBP
通过"打开文件夹"按钮选择任何包含图片的文件夹
灵活的排序选项:
按时间排序(新→旧或旧→新)
按文件名排序(A→Z或Z→A)
键盘快捷键支持(左右箭头切换图片,Delete删除图片,F5刷新)
显示文件名和修改时间。当图片尺寸小于或等于显示区域时,会按原尺寸显示;只有当图片尺寸大于显示区域时,才会按比例缩放。同时,文件名标签会显示图片的原始尺寸,让你知道图片的实际大小。
运行效果
本程序要使用Pillow库的Image和ImageTk模块,它是第三方库,需要安装Pillow库(Pillow是PIL的一个分支,提供了更好的维护和更新)。详情可见https://blog.csdn.net/cnds123/article/details/126141838
源码如下:
import os
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
from PIL import Image, ImageTk
import datetime
import reclass ImageViewer:def __init__(self, root, initial_dir=None):self.root = rootself.root.title("图片浏览器")self.current_dir = initial_dirself.current_index = 0self.images = []self.filtered_images = [] # 初始化为空列表self.photo = None # 保存当前显示的图片引用self.supported_formats = ('.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.webp')# 创建UIself.create_ui()# 窗口大小变化时重新调整图片self.root.bind("<Configure>", self.on_resize)# 如果提供了初始目录,加载图片if self.current_dir and os.path.exists(self.current_dir):self.load_images()else:self.select_folder()def load_images(self):"""加载当前文件夹中的所有图片"""if not self.current_dir or not os.path.exists(self.current_dir):returnself.images = []files = os.listdir(self.current_dir)# 筛选支持的图片格式for file in files:if file.lower().endswith(self.supported_formats):# 获取文件修改时间file_path = os.path.join(self.current_dir, file)mod_time = os.path.getmtime(file_path)mod_time_str = datetime.datetime.fromtimestamp(mod_time).strftime('%Y-%m-%d %H:%M:%S')self.images.append((file, mod_time_str, mod_time))# 按修改时间排序,最新的在前面self.images.sort(key=lambda x: x[2], reverse=True)# 更新UIself.update_ui_after_load()def update_ui_after_load(self):"""更新加载图片后的UI状态"""# 更新文件夹标签self.folder_label.config(text=self.current_dir)# 更新滑动条范围self.filtered_images = self.images.copy()self.update_slider_range()# 显示第一张图片self.current_index = 0if self.filtered_images:self.show_image(0)else:self.clear_image()messagebox.showinfo("提示", "当前文件夹没有支持的图片文件")def create_ui(self):# 主框架main_frame = ttk.Frame(self.root, padding="10")main_frame.pack(fill=tk.BOTH, expand=True)# 顶部控制区域control_frame = ttk.Frame(main_frame)control_frame.pack(fill=tk.X, pady=(0, 10))# 当前文件夹显示folder_frame = ttk.Frame(control_frame)folder_frame.pack(side=tk.LEFT, fill=tk.X, expand=True)ttk.Label(folder_frame, text="当前文件夹:").pack(side=tk.LEFT)self.folder_label = ttk.Label(folder_frame, text="未选择", font=("Arial", 9, "italic"))self.folder_label.pack(side=tk.LEFT, padx=5)# 打开文件夹按钮ttk.Button(folder_frame, text="打开文件夹", command=self.select_folder).pack(side=tk.LEFT, padx=5)# 排序选项sort_frame = ttk.Frame(main_frame)sort_frame.pack(fill=tk.X, pady=(0, 10))ttk.Label(sort_frame, text="排序方式:").pack(side=tk.LEFT)self.sort_var = tk.StringVar(value="时间(新→旧)")sort_options = ["时间(新→旧)", "时间(旧→新)", "名称(A→Z)", "名称(Z→A)"]sort_combo = ttk.Combobox(sort_frame, textvariable=self.sort_var, values=sort_options, width=12)sort_combo.pack(side=tk.LEFT, padx=5)sort_combo.bind("<<ComboboxSelected>>", self.sort_images)# 刷新按钮ttk.Button(sort_frame, text="刷新", command=self.refresh).pack(side=tk.RIGHT)# 图片显示区域self.image_frame = ttk.Frame(main_frame, borderwidth=1, relief="solid")self.image_frame.pack(fill=tk.BOTH, expand=True, pady=5)self.image_label = ttk.Label(self.image_frame)self.image_label.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)# 信息显示区域info_frame = ttk.Frame(main_frame)info_frame.pack(fill=tk.X, pady=(5, 10))self.file_label = ttk.Label(info_frame, font=("Arial", 10, "bold"))self.file_label.pack(side=tk.LEFT)self.time_label = ttk.Label(info_frame, font=("Arial", 10), foreground="#007acc")self.time_label.pack(side=tk.RIGHT)# 计数显示count_frame = ttk.Frame(main_frame)count_frame.pack(fill=tk.X, pady=(0, 5))self.count_label = ttk.Label(count_frame, font=("Arial", 9))self.count_label.pack(side=tk.RIGHT)# 滑动条slider_frame = ttk.Frame(main_frame)slider_frame.pack(fill=tk.X, pady=(0, 5))ttk.Button(slider_frame, text="◀", width=3, command=self.prev_image).pack(side=tk.LEFT)self.slider = ttk.Scale(slider_frame, orient=tk.HORIZONTAL, from_=0, to=0, command=self.slider_changed)self.slider.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)ttk.Button(slider_frame, text="▶", width=3, command=self.next_image).pack(side=tk.LEFT)# 底部按钮区域button_frame = ttk.Frame(main_frame)button_frame.pack(fill=tk.X, pady=(5, 0))ttk.Button(button_frame, text="在资源管理器中打开", command=self.open_in_explorer).pack(side=tk.LEFT)ttk.Button(button_frame, text="删除当前图片", command=self.delete_current).pack(side=tk.RIGHT)# 键盘快捷键self.root.bind("<Left>", lambda e: self.prev_image())self.root.bind("<Right>", lambda e: self.next_image())self.root.bind("<Delete>", lambda e: self.delete_current())self.root.bind("<F5>", lambda e: self.refresh())# 初始化标签self.clear_image()def select_folder(self):"""选择图片文件夹"""initial_dir = self.current_dir if self.current_dir else os.path.expanduser("~")new_dir = filedialog.askdirectory(title="选择图片文件夹", initialdir=initial_dir)if new_dir: # 如果用户选择了文件夹self.current_dir = new_dirself.load_images()def on_resize(self, event):"""窗口大小变化时重新调整当前图片"""# 只有当事件来自根窗口且有图片显示时才处理if (event.widget == self.root and hasattr(self, 'filtered_images') and self.filtered_images and hasattr(self, 'current_index')):# 使用延迟调用避免过于频繁的刷新if hasattr(self, 'resize_job'):self.root.after_cancel(self.resize_job)self.resize_job = self.root.after(100, lambda: self.show_image(self.current_index))def sort_images(self, event=None):"""根据选择的排序方式对图片进行排序"""if not hasattr(self, 'filtered_images') or not self.filtered_images:returnsort_method = self.sort_var.get()if sort_method == "时间(新→旧)":self.filtered_images.sort(key=lambda x: x[2], reverse=True)elif sort_method == "时间(旧→新)":self.filtered_images.sort(key=lambda x: x[2])elif sort_method == "名称(A→Z)":self.filtered_images.sort(key=lambda x: x[0].lower())elif sort_method == "名称(Z→A)":self.filtered_images.sort(key=lambda x: x[0].lower(), reverse=True)# 重新显示当前图片if self.filtered_images:self.current_index = 0self.show_image(0)def update_slider_range(self):"""更新滑动条范围"""max_val = max(0, len(self.filtered_images) - 1)self.slider.configure(to=max_val)if max_val > 0:self.slider.configure(state="normal")else:self.slider.configure(state="disabled")def slider_changed(self, value):"""滑动条值变化时的回调"""try:index = int(float(value))if index != self.current_index:self.show_image(index)except ValueError:passdef show_image(self, index):"""显示指定索引的图片"""if not hasattr(self, 'filtered_images') or not self.filtered_images or index >= len(self.filtered_images):self.clear_image()returnif 0 <= index < len(self.filtered_images):self.current_index = indexfilename, time_str, _ = self.filtered_images[index]filepath = os.path.join(self.current_dir, filename)if os.path.exists(filepath):# 加载图片try:image = Image.open(filepath)# 获取图片原始尺寸width, height = image.size# 获取显示区域大小self.root.update_idletasks() # 确保尺寸已更新frame_width = max(1, self.image_frame.winfo_width() - 20) # 确保至少为1frame_height = max(1, self.image_frame.winfo_height() - 20)# 判断图片是否需要缩放if width <= frame_width and height <= frame_height:# 小图片按原尺寸显示new_width, new_height = width, heightresized_image = imageelse:# 大图片按比例缩放scale = min(frame_width/max(1, width), frame_height/max(1, height))new_width = max(1, int(width * scale))new_height = max(1, int(height * scale))resized_image = image.resize((new_width, new_height), Image.LANCZOS)self.photo = ImageTk.PhotoImage(resized_image)self.image_label.config(image=self.photo)# 更新滑动条位置self.slider.set(index)# 更新文件名和时间标签self.file_label.config(text=f"{filename} ({width}x{height})")self.time_label.config(text=time_str)self.count_label.config(text=f"{index+1}/{len(self.filtered_images)}")# 更新窗口标题self.root.title(f"图片浏览器 - {filename}")except Exception as e:self.clear_image()self.file_label.config(text=f"无法加载图片: {str(e)}")else:self.clear_image()self.file_label.config(text="文件不存在")def clear_image(self):"""清除当前显示的图片"""self.image_label.config(image='')self.photo = Noneself.file_label.config(text="没有找到图片")self.time_label.config(text="")self.count_label.config(text="0/0")self.root.title("图片浏览器")def next_image(self):"""显示下一张图片"""if hasattr(self, 'filtered_images') and self.filtered_images and self.current_index < len(self.filtered_images) - 1:self.show_image(self.current_index + 1)def prev_image(self):"""显示上一张图片"""if hasattr(self, 'filtered_images') and self.filtered_images and self.current_index > 0:self.show_image(self.current_index - 1)def refresh(self):"""刷新当前文件夹中的图片"""if self.current_dir:current_file = Noneif hasattr(self, 'filtered_images') and self.filtered_images and self.current_index < len(self.filtered_images):current_file = self.filtered_images[self.current_index][0]self.load_images()# 尝试恢复到之前查看的图片if current_file and self.filtered_images:for i, (filename, _, _) in enumerate(self.filtered_images):if filename == current_file:self.show_image(i)return# 如果找不到之前的图片,显示第一张if self.filtered_images:self.show_image(0)def open_in_explorer(self):"""在文件资源管理器中打开当前文件夹"""if self.current_dir and os.path.exists(self.current_dir):if os.name == 'nt': # Windowsos.startfile(self.current_dir)elif os.name == 'posix': # macOS 或 Linuximport subprocessimport syssubprocess.call(('open' if sys.platform == 'darwin' else 'xdg-open', self.current_dir))def delete_current(self):"""删除当前显示的图片"""if not hasattr(self, 'filtered_images') or not self.filtered_images or not hasattr(self, 'current_index') or self.current_index >= len(self.filtered_images):returnfilename, _, _ = self.filtered_images[self.current_index]filepath = os.path.join(self.current_dir, filename)if os.path.exists(filepath):# 确认删除if messagebox.askyesno("确认删除", f"确定要删除这张图片吗?\n{filename}"):try:os.remove(filepath)# 从列表中移除del self.filtered_images[self.current_index]# 更新原始列表self.images = [img for img in self.images if img[0] != filename]# 更新滑动条范围self.update_slider_range()# 显示下一张图片或清空if self.filtered_images:# 如果删除的是最后一张,显示新的最后一张if self.current_index >= len(self.filtered_images):self.current_index = len(self.filtered_images) - 1self.show_image(self.current_index)else:self.clear_image()messagebox.showinfo("删除成功", "图片已删除")except Exception as e:messagebox.showerror("删除失败", f"无法删除文件: {str(e)}")# 使用方法
if __name__ == "__main__":import sysinitial_dir = Noneif len(sys.argv) > 1:initial_dir = sys.argv[1]root = tk.Tk()root.title("图片浏览器")root.geometry("1000x800")# 设置最小窗口大小root.minsize(800, 600)# 初始化应用app = ImageViewer(root, initial_dir)root.mainloop()
相关文章:
Python实现图片浏览器
Python实现图片浏览器 支持浏览多种常见图片格式:JPG, JPEG, PNG, GIF, BMP, TIFF, WEBP 通过"打开文件夹"按钮选择任何包含图片的文件夹 灵活的排序选项: 按时间排序(新→旧或旧→新) 按文件名排序(A→…...
网页设计规范:从布局到交互的全方位指南
网页设计规范看似繁杂,但其实都是为了给用户提供更好的体验。只有遵循这些规范,才能设计出既美观又实用的网页,让用户在浏览网页时感到舒适、愉悦。 一、用户体验至上 用户体验(UX)是网页设计的核心原则之一。设计师…...
哪些心电图表现无缘事业编体检呢?
根据《公务员录用体检通用标准》心血管系统条款及事业单位体检实施细则,心电图不合格主要涉及以下类型及处置方案: 一、心律失常类 早搏:包括房性早搏、室性早搏和交界性早搏。如果每分钟早搏次数较多(如超过5次)&…...
Java基础系列-HashMap源码解析1-BST树
文章目录 序二叉搜索树(BST)引入查找5插入9极端情况删除删除叶节点 10删除节点只有左子树或只有右子树删除节点既有左子树又有右子树为什么这么代替? 序 提到HashMap,就不得不提红黑树(HashMap1.8之后)&am…...
生物计算安全攻防战:从DNA存储破译到碳基芯片防御体系重构
随着碳基生物芯片突破冯诺依曼架构限制,DNA数据存储密度达到1EB/克量级,合成生物学与信息技术的融合正引发新一轮安全革命。本文深入解析碳基芯片逆向工程路径,揭示酶驱动DNA数据解码的技术突破,预警合成生物回路潜在的数据泄露风…...
【金仓数据库征文】从Oracle到KingbaseES的语法兼容与迁移
随着“信创”战略的深入推进,国产数据库逐渐成为IT系统的重要组成部分。KingbaseES(金仓数据库)凭借其良好的Oracle兼容性和日益完善的生态,成为金融、政务等核心行业国产化替代的重要选项。本文将从语法兼容性分析出发࿰…...
MATLAB 下载安装教程
## 一、下载MATLAB 1. 访问 MathWorks 官方网站:https://www.mathworks.com/ 2. 点击右上角的"登录"按钮 - 如果没有账号,需要先注册一个 MathWorks 账号 - 学生可以使用教育邮箱注册,获得教育版授权 3. 登录后,点击&…...
Android kotlin通知功能完整实现指南:从基础到高级功能
本文将详细介绍如何在Android应用中实现通知功能,包括基础通知、动作按钮和内联回复等高级特性。 一、基础通知实现 1. 基本通知发送方法 fun sendBasicNotification(context: Context, title: String, message: String) {// 1. 创建通知渠道(Android 8.0必需)va…...
Javase 基础入门 —— 04 继承
本系列为笔者学习Javase的课堂笔记,视频资源为B站黑马程序员出品的《黑马程序员JavaAI智能辅助编程全套视频教程,java零基础入门到大牛一套通关》,章节分布参考视频教程,为同样学习Javase系列课程的同学们提供参考。 01 什么是继…...
2.4/Q2,Charls最新文章解读
文章题目:The impact of hearing ability on depression among retired middle-aged and elderly individuals in China: the chain mediating role of self-rated health and life satisfaction DOI:10.1186/s41043-025-00791-9 中文标题:中…...
对流对象的理解
在c里,“流”可以理解为数据传输与操作的“介质”。 从输入输出角度来看,有输入流(比如cin)和输出流(cout)。对于输入流,数据通过它从外部设备(例如键盘)“流入”程序内…...
RBAC权限-笔记
1. RBAC模型简介 1.1. RBAC三要素 RBAC权限模型(Role-Based Access Control:基于角色的访问控制)有3个基础组成部分,分别是:用户、角色和权限。它们之间的关系如下图所示: 用户(User)…...
stm32之GPIO函数详解和上机实验
目录 1.LED和蜂鸣器1.1 LED1.2 蜂鸣器 2.实验2.1 库函数:RCC和GPIO2.1.1 RCC函数1. RCC_AHBPeriphClockCmd2. RCC_APB2PeriphClockCmd3. RCC_APB1PeriphClockCmd 2.1.2 GPIO函数1. GPIO_DeInit2. GPIO_AFIODeInit3. GPIO_Init4. GPIO_StructInit5. GPIO_ReadInputDa…...
MsQuick编译和使用
MsQuick编译和使用 编译克隆代码使用cmakevs2022编译 使用示例 编译 克隆代码 git clone --recurse-submodules https://github.com/microsoft/msquic.git使用cmakevs2022编译 然后直接configure之后Generate然后打开vs工程编译即可生成动态库 使用示例 #include <s…...
01 ubuntu中wps桌面快捷键无法使用
文章目录 1. 问题描述:2. 解决方法:3. 结果展示4. 参考 1. 问题描述: 2. 解决方法: 添加权限 chmod 755 ./wps-office-prometheus.desktop 右键选择允许运行 3. 结果展示 修改前 修改后 4. 参考 参考1...
云原生后端架构:重塑后端开发的新范式
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:后端开发的新时代正在到来 传统的后端开发常常面临如下挑战:部署流程复杂、环境不一致、系统难以扩展、监控能力薄弱、上线流程缓慢。在企业数字化转型、业务快速迭代的大背景下,这些问题暴露得…...
Linux命令-tcpdump
tcpdump 是一个功能强大的网络数据包捕获和分析工具。以下是 tcpdump 命令的完整参数列表及说明: 参数 -a 将网络地址和广播地址转换为名字 tcpdump -a -i eth0-A 以 ASCII 格式打印所有分组,最小化链路层头部信息 tcpdump -A-b 在数据链路层上选择协议…...
分糖果——牛客
链接:登录—专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 幼儿园准备了nnn包糖果,每包糖果里有111、222或333颗美味的糖果。现在需要将这些这些糖果平分给两个表现优异的小朋友以作奖励,为了公平公正,需要…...
L0、L2和L∞范数这三种范数的区别
目录 一、解释 1. L0范数:数一数你有多少件行李 2. L2范数:别把行李塞得太满 3. L∞范数:别带任何超重的东西 一句话总结 二、作用 1. L0范数的作用:做减法,只留最重要的…...
[实战]zynq7000设备树自动导出GPIO
目录 zynq7000设备树自动导出GPIO添加设备树节点验证实验 结论 zynq7000设备树自动导出GPIO 今天无聊,掏出我82年产的microzed玩一玩。玩啥好呢,要不点个灯吧。于是,三下五除二,通过linux sys接口以及echo,很快就点亮…...
java六人打分
import java.util.Scanner;public class HelloWorld {public static void main(String[] args) {//打分平均分System.out.println("请输入六个评分");Scanner sc new Scanner(System.in);double[] score new double[6];for(int i0;i<score.length;i){System.ou…...
量子计算浪潮下的安全应对之法
量子计算凭借其强大的计算能力,被传言能够在极短时间内秒级破解传统计算机需耗时漫长岁月(以万年算)才能解开的密码,成为了近年来人们讨论的热点。这看似高深的科技名词在网络安全中又扮演着何种角色?我们应从当前人们…...
Windows Server 2022 常见问题解答
一、安装与部署 1.1 系统要求 硬件配置:最低需要 1.4 GHz 64 位处理器、512 MB 内存、32 GB 硬盘空间。但在实际生产环境中,为确保系统流畅运行,建议使用 2.0 GHz 以上处理器、8 GB 以上内存和 100 GB 以上硬盘。软件兼容性:与大多数基于 Windows 的企业级应用兼容,但在安…...
项目组合管理PPM
项目组合管理(Project Portfolio Management, PPM)详述 一、定义与核心目标 定义 项目组合管理是通过系统化的方法,对组织的所有项目和项目集进行识别、选择、优先级排序、资源配置和动态监控,以确保其与战略目标一致,并最大化投资回报(ROI)的管理过程。 核心目标 战略…...
自建开源远程协助服务RustDesk —— 筑梦之路
开源项目 # 服务端https://github.com/rustdesk/rustdesk-server.git# 客户端https://github.com/rustdesk/rustdesk.git 搭建服务端 需要使用的端口、协议 hbbs - RustDesk ID 注册服务器 hbbr - RustDesk 中继服务器默认情况下,hbbs 监听 21115(tcp) , 21…...
【android bluetooth 协议分析 11】【AVDTP详解 2】【avdtp 初始化阶段主要回调关系梳理】
在车机中 a2dp 通常情况下作为 sink. 本篇来帮助各位 朋友梳理一下,这部分的初始化流程。 我们着重梳理 native 层的逻辑, framework - java 侧一般比较容易看明白, 暂时不做梳理。 如果需要笨叔梳理的可以在博客评论。 出专门的章节来梳理。…...
C++回顾 day3
宏定义的数据是在预处理发生了替换 const类型的数据是在编译阶段发生的替换 命名空间 namespace 空间名{int a;void func_print(){printf("func_print");}struct Stu{int x;char *y;};//或者其他命名空间 } Space::x 20; cout << Space::x;using Space::x;…...
机器学习算法-分类决策树
分类决策树算法-python实现 数据集 具体方法是:从根结点开始,对结点计算所有可能的特征的信息增益,选择信息增益最大的特征作为结点的特征,由该特征的不同取值建立子节点;再对子结点递归地调用以上方法,构…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(9): 意向形
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(9): 意向形 1、前言(1)情况说明(2)工程师的信仰 2、知识点(1)「~てしまう」=「~ちゃう…...
kotlin与MVVM结合使用总结(一)
一、Kotlin 与 MVVM 结合的核心优势 代码简洁性 数据类(data class)简化 Model 层定义,自动生成equals/hashCode/toString扩展函数简化 View 层逻辑(如点击事件扩展)lateinit/by lazy优化 ViewModel 属性初始化 异步处…...
达妙电机CAN通信及实验
项目进一步往下做的时候,要上实物了,需要用到达妙电机,虽然有说明书和例程,但是STM32控制电机的具体时间还是花了些时间,我的板子和例程的有些区别,中间很多地方都需要进行修改完善,而且还补充了…...
语音合成之四基于LLM的语音合成
基于LLM的语音合成 1.技术架构1.1 LlaSA1.2 CosyVoice (和 CosyVoice2)1.3 SparkTTS 2 特性对比2.1 零样本语音克隆2.2 多语种支持2.3 可控语音生成2.4 计算效率和模型大小 总结 当前,在大型语言模型(Large Language Models,LLMs)…...
Docker Python 官方镜像使用说明(TAG说明)
Docker Python 官方镜像使用说明(TAG说明) 本文将以python的3.12版本,详细讲解官方 Python 镜像 的TAGS含义 官方文档:https://github.com/tuonioooo/docker 🧭 一张图先看懂(最常见 Tag) py…...
Node.js 开发用户登录功能(使用mysql实现)
在 Web 开发中,用户登录功能是一个基础且重要的部分。、 一、环境搭建 在开始开发之前,我们需要搭建好相应的开发环境。以下是所需的工具和库: Node.js:作为 JavaScript 的运行环境,为我们的项目提供支持。mysql2&am…...
程序员学英文之Shipment Claim 运输和索赔
Time is precious , don’t waste your time, you should spend your time on something valuable . 时间很宝贵,不要浪费时间,你应该把时间用在有 价值的事情上。 Dia-1: Shipment by Voyage Charter 租船装运 1. May I know when your bo…...
python实战项目64:selenium采集软科中国大学排名数据
python实战项目64:selenium采集软科中国大学排名数据 一、项目需求二、流程分析三、完整代码一、项目需求 本项目的需求是使用selenium采集软科中国大学排名的数据。网站首页如下: 抓取此网页数据一般有两种方式,一种是直接发requests请求,我们这里采用的是使用selenium控…...
Linux服务器:在ufw防火墙设置这套规则sudo ufw allow from 172.0.0.0/8,为什么容器就可以访问宿主机的服务了?
在 Docker 环境中,容器默认使用 桥接网络(bridge),宿主机和容器之间的通信会受到防火墙(如 ufw)的限制。当你执行 sudo ufw allow from 172.0.0.0/8 后,容器可以访问宿主机上的服务,原因如下: 1. Docker 默认使用 172.x.x.x 网段 Docker 默认会创建一个 docker0 网桥…...
Google搜索技巧
谷歌搜索 1. 使用双引号 (" ") 精确匹配短语 ● 例子:"人工智能的定义" ● 作用:确保搜索结果中包含完全匹配的短语,而不是单独的单词。 2. 使用减号 (-) 排除特定词语 ● 例子:苹果 -水果 ● 作用&…...
Reactor编程模型介绍
Reactor 模型是一种基于事件驱动的编程模型,广泛应用于高并发网络服务器的设计中。它通过事件循环和回调机制,将事件的处理逻辑从主线程中解耦出来,从而实现高效的异步 I/O 操作。Reactor 模型的核心思想是利用一个或多个事件分发器(Reactor)来监听各种事件(如 I/O 事件、…...
C++笔记-stack_queue(含deque,priority_queue,仿函数的讲解)
一.stack和queue的基本使用 stack和queue就是我们之前所学的栈和队列,这两个和之前学的vector,list不太一样: 这是vector和list的,注意第一行中写的containers,代表这两个都是容器,但是: stac…...
意见反馈留言二维码制作
意见反馈对于工作整改具有重要作用,在工作中一味埋头苦干不如抬头多听听反馈声音。而传统的反馈内容投递后,因为繁琐性和时效性的枷锁,往往石沉大海,不知何时才能得到回应,这就导致反馈信息的延迟,一些时效…...
扣子智能体平台深度解读:功能剖析与全流程工作流详解
在上一篇文章中,我们已经带大家了解了“智能体”这一概念的内涵,并通过扣子智能体平台的各大模块做了初步介绍,同时用一个简单的示例演示了如何构建和部署第一个智能体。那篇文章打好了基础,让大家对智能体的基本组成与工作方式有…...
C语言五子棋项目
头文件与宏定义 #include <graphics.h> #include <conio.h> graphics.h:EasyX 图形库,提供图形绘制功能(画线、画圆、显示文字等)。 conio.h:提供控制台输入输出函数(这里只是为了兼容性&…...
建筑安全员 A 证与 C 证:差异决定职业方向
在建筑行业的职业发展道路上,安全员 A 证和 C 证就像两条不同的岔路,它们之间的差异,在很大程度上决定了从业者的职业方向。 从证书性质和用途来看,A 证是从业资格证书,更像是一把开启安全管理高层岗位的 “金钥匙”。…...
长连接、短连接与WebSocket的基本知识
目录 前言正文 前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 爬虫神器,无代码爬取,就来:bright.cn Java基本知识: java框架 零基础从入门到精通的学习路线 附…...
MySQL常见问题解答
一、安装与配置问题 1. 安装失败(权限 / 依赖 / 端口冲突) 权限问题:以管理员身份运行安装程序(Windows)或使用sudo(Linux)。依赖缺失: Windows 需安装 Visual C++ Redistributable(如 2013 版)。Linux 通过包管理器安装依赖(如libaio、perl)。端口冲突: 检查 33…...
Codeforces Round 1019 (Div. 2)(ABCD)
A. Common Multiple 翻译: 给你一个整数数组 a1,a2,...,an。如果存在一个数组 y1,y2,...,ym,且 y 的元素是不同的(换句话说,对于所有 1≤i<j≤m 的数组,yi≠yj),并且对于所有 1≤i≤m 的数组…...
爬虫学习总结
通过前几次课,我们学习了爬虫的相关基础知识。 以下是我对爬虫学习做的一些总结: 一、认识爬虫:开启数据抓取之旅 1.1 什么是网络爬虫 网络爬虫就像是一个不知疲倦的 “数据搬运工”,它能按照预先设定的规则,自动…...
UE5的 Modify Curve 蓝图节点
In Unreal Engine’s Animation Blueprints, the Modify Curve node lets you drive and alter any named Animation Curve on your character at runtime. The Apply Mode setting on that node controls how the “new” value you feed in (via the added curve‐input pin)…...
鸿蒙中的并发线程间通信、线程间通信对象
目录 并发线程间通信1. 线程间通信对象1.1 普通对象1.2 ArrayBuufer对象1.3 SharedArrayBuffer对象1.4 Transferable对象(NativeBinding对象)1.5 Sendable对象简介异步锁ASON解析与生成共享容器共享模块Sendable对象冻结 2 线程间通信场景2.1 使用TaskPo…...