Python情人节浪漫代码:心情泡泡动画小项目实现教程
每年情人节前后总有人问我Python除了写爬虫、做自动化到底能不能搞点浪漫的东西其实能而且门槛低到让人意外。今天这篇就分享一个可以直接拿去送人的小项目python情人节代码之心情泡泡。它的玩法很简单——把你想说又不好意思直接打出来的话装进一个个半透明的小泡泡里让它们在屏幕上慢慢浮起来鼠标一点泡泡会“啪”地原地绽开露出里面藏好的情话。我把整个项目的需求定义、技术选型、完整代码、打包发布和踩坑经验都放在这篇里。无论你是第一次接触GUI编程还是已经写过不少脚本想换个花样都可以照着一步步做完。收到礼物的人不需要装环境、不需要懂Python你最终要交付的是一个双击就能跑起来的exe文件。项目本身不大但该踩的坑一个不少比如中文字体、窗口透明、打包后资源路径、高分屏缩放这些我会全部讲到。1. 先想清楚成品效果别人收到的究竟是个什么东西写代码之前我建议先花十分钟把“成品长什么样”在脑子里过一遍。很多人拿到这类项目就急着敲代码结果做到一半发现效果不是自己想要的返工成本比一开始想清楚高得多。心情泡泡这个项目我一开始设想的最终效果是程序启动后出现一个独立小窗口窗口背景用深夜到玫瑰色的渐变整体氛围接近“安静的夜晚里一场小型的浪漫心事浮起”窗内不断有半透明的彩色泡泡从底部向上飘每个泡泡的颜色、大小、上升速度都不同视觉上像是一堆心事在慢慢浮出鼠标点中某个泡泡后泡泡消失原地变成一张圆角小卡片显示你预先写好的那句话卡片停留大约4秒后自动淡出窗口继续飘新的泡泡用户可以随时右键退出不会出现“点不关、杀不掉”的尴尬。把效果定义清楚以后技术选型就好做了。很多东西看起来效果好但做出来的体积、复杂度、稳定性都会超出预期。收纳礼物的场景有一个共性对方大概率完全不懂编程你的代码越“不挑环境”、越“傻瓜化”越容易成功。所以我从一开始就放弃了“网页HTML版本”“游戏引擎版本”这类方案最后直接在Python GUI框架里挑。这个项目适合什么人参考很简单学完Python基础语法想做一个有实际交付结果的练手项目或者想在情人节、纪念日、生日给身边的人一点不一样的小惊喜。不需要懂图形学不需要会算法基础逻辑就是“生成泡泡 让泡泡动 点击弹出文字”。1.1 先确定一句话词库别等到写代码才想内容我把“心情泡泡”的核心内容定义成一句话词库。你打算让泡泡承载的文字是整个项目的灵魂也是你后续调试时最直观的反馈。默认情话库可以随自己心意写我建议每句话不要超过20个字太长的话卡片显示起来像论文摘要氛围感直接没了。我提供一组默认词库直接在代码里使用遇见你之后我的每一个分支都是happy end你是我这辈子最想修好的关系今天也想你比昨天多了一点点世界的bug很多但想到你一切都能运行我想和你一起把日子过成一首慢诗晚安明天也一起好吗你不在身边的日子我用回忆补丁续命认识你之前人生是REPL认识你之后人生有了完整的脚本如果想让项目在真正送出的时候更贴心可以在exe同目录放一个messages.txt每行一句话程序启动时会优先读取这个文件没有这个文件时就用内置词库。这样你可以反复改词不用重新打包也不用打开代码编辑器。这个细节在后面资源路径章节会细说。2. 为什么选PyQt5和Pygame、tkinter比完就不纠结了很多人一听到“Python做动画效果”第一反应是Pygame其实这种轻度交互项目用Pygame并不舒服。下面这张表可以帮你快速建立判断标准方案动画能力文字排版与卡片效果开发效率打包体积tkinter性能一般强行高频重绘会闪或卡圆角、半透明、渐变这些效果写起来非常费劲中小Pygame强适合粒子、物理、碰撞游戏UI组件基本没有文字弹窗、右键菜单要自己造低中PyQt5足够QTimer驱动paintEvent稳定流畅自带QLabel、QMenu、样式表圆角半透明很容易高偏大但可控Pygame适合做真正的物理泡泡、泡泡互相碰撞、挤压、飘动轨迹复杂的场景代码量至少翻两倍。如果你只是想做一个“点击后弹出情话卡片”的礼物程序核心是界面排版和事件交互PyQt5是最省力的选择。tkinter虽然零依赖但做半透明渐变效果的体验实在不好而且最终还是要打包等于没省事。还有一点要说清楚PyQt5虽然是第三方库但只要你的电脑上能正常pip install pyqt5它就不会给你的项目带来平台兼容性问题。Windows、macOS、Linux都能跑而且它支持无边框透明窗口这给后面的“高级全屏模式”留了扩展空间。我用PyQt5跑下来的结论是开发效率、稳定性、表现力三者平衡得最好。3. 动手实现一个能直接跑起来的情人节心情泡泡代码下面是完整的Python代码。我建议你新建一个文件夹bubble_gift把下面的内容保存为valentine_bubbles.py然后pip install pyqt5再运行就可以了。# -*- coding: utf-8 -*- import sys import os import math import random from PyQt5.QtCore import Qt, QTimer, QPointF from PyQt5.QtGui import QPainter, QColor, QFont, QRadialGradient, QLinearGradient from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QMenu, QAction def load_words(): 优先读取 exe/脚本同目录下的 messages.txt每行一句没有则用内置词库。 try: base_dir os.path.dirname(os.path.abspath(sys.argv[0])) msg_file os.path.join(base_dir, messages.txt) if os.path.exists(msg_file): with open(msg_file, r, encodingutf-8) as f: lines [line.strip() for line in f if line.strip()] if lines: return lines except Exception: pass return [ 遇见你之后我的每一个分支都是 happy end, 你是我这辈子最想修好的关系, 今天也想你比昨天多了一点点, 世界的 bug 很多但想到你一切都能运行, 我想和你一起把日子过成一首慢诗, 晚安明天也一起好吗, 你不在身边的日子我用回忆补丁续命, 认识你之前人生是 REPL认识你之后人生有了完整的脚本, ] class Bubble: 单个心情泡泡记录位置、速度、大小、颜色、透明度与要展示的文字。 def __init__(self, width, height): self.radius random.uniform(45, 75) self.x random.uniform(self.radius, width - self.radius) self.base_x self.x self.y height random.uniform(-20, 80) self.vy random.uniform(90, 170) # 向上飘的速度 self.hue random.randint(0, 359) # 色相 self.alpha random.randint(60, 180) # 透明度 self.phase random.uniform(0, math.pi * 2) # 横向摆动相位 self.word random.choice(load_words()) def move(self, dt): self.y - self.vy * dt self.phase dt * 1.5 self.x self.base_x math.sin(self.phase) * 14 def is_out(self, top): return self.y self.radius top def hit_test(self, px, py): dx px - self.x dy py - self.y return dx * dx dy * dy self.radius * self.radius class BubbleWindow(QWidget): def __init__(self): super().__init__() self.setWindowTitle(心情泡泡) self.resize(780, 980) self.bubbles [] self.paused False self.frame_timer QTimer(self) self.frame_timer.timeout.connect(self.on_frame) self.frame_timer.start(33) # 约 30 FPS self.spawn_timer QTimer(self) self.spawn_timer.timeout.connect(self.spawn) self.spawn_timer.start(450) # 每 0.45 秒生成一个泡泡 def spawn(self): if len(self.bubbles) 18: self.bubbles.append(Bubble(self.width(), self.height())) def on_frame(self): dt self.frame_timer.interval() / 1000.0 for b in self.bubbles: b.move(dt) self.bubbles [b for b in self.bubbles if not b.is_out(-100)] self.update() def paintEvent(self, event): painter QPainter(self) painter.setRenderHint(QPainter.Antialiasing) # 背景渐变深夜色过渡到玫瑰色 rect self.rect() grad QLinearGradient(0, 0, 0, rect.height()) grad.setColorAt(0.0, QColor(24, 8, 48)) grad.setColorAt(0.5, QColor(74, 18, 78)) grad.setColorAt(1.0, QColor(148, 42, 76)) painter.fillRect(rect, grad) # 画每个泡泡 for b in self.bubbles: color QColor() color.setHsv(b.hue, 220, 230, b.alpha) highlight QColor(255, 255, 255, b.alpha) edge_color QColor(b.hue, 140, 190, 80) rad_grad QRadialGradient( b.x - b.radius * 0.2, b.y - b.radius * 0.2, b.radius * 1.3 ) rad_grad.setColorAt(0.0, highlight) rad_grad.setColorAt(0.35, color) rad_grad.setColorAt(1.0, edge_color) painter.setBrush(rad_grad) painter.setPen(Qt.NoPen) painter.drawEllipse(QPointF(b.x, b.y), b.radius, b.radius) def mousePressEvent(self, event): if event.button() Qt.LeftButton: px, py event.pos().x(), event.pos().y() for b in self.bubbles: if b.hit_test(px, py): self.bubbles.remove(b) self.show_card(px, py, b.word) return elif event.button() Qt.RightButton: menu QMenu(self) action QAction(暂停/继续, menu) action.triggered.connect(self.toggle_paused) menu.addAction(action) exit_action QAction(退出, menu) exit_action.triggered.connect(self.close) menu.addAction(exit_action) menu.exec_(event.globalPos()) def toggle_paused(self): self.paused not self.paused if self.paused: self.frame_timer.stop() self.spawn_timer.stop() else: self.frame_timer.start() self.spawn_timer.start() def show_card(self, x, y, word): 点击泡泡后在原地生成一张承载情话的卡片4秒后自动消失。 card QLabel(self) card.setText(word) card.setFont(QFont(微软雅黑, 12)) card.setWordWrap(True) card.setStyleSheet( background-color: rgba(255, 255, 255, 235); color: #333333; border-radius: 18px; padding: 18px 22px; ) card.adjustSize() w, h card.width(), card.height() # 边界修正避免卡片在窗口边缘被截断 left max(8, min(x - w // 2, self.width() - w - 8)) top max(8, min(y - h - 20, self.height() - h - 8)) card.move(left, top) card.show() card.raise_() QTimer.singleShot(4000, card.deleteLater) if __name__ __main__: QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True) app QApplication(sys.argv) app.setFont(QFont(微软雅黑, 10)) win BubbleWindow() win.show() sys.exit(app.exec_())你直接复制运行大概就能看到效果了。如果你用的是macOS或者Linux代码里的字体微软雅黑可以改成自己系统里存在的中文字体否则会显示成方块。Windows下这个字体基本是必有的正常双击运行不需要担心。3.1 这个代码最需要注意的三个位置第一个是load_words()函数。我写它的时候故意没有只放一个列表而是让它优先尝试读取同目录的messages.txt。这是因为打包成exe之后改内容最友好的方式就是改外部文本文件而不是重新打包整个程序。你以后想换一句情话只用编辑txt再保存连重启程序都不用下一批泡泡就会用新词。第二个是Bubble类的move方法。它里面除了让泡泡向上升还加了一个正弦摆动self.x self.base_x math.sin(self.phase) * 14。没有这行的话泡泡只会直直往上飘整个画面会显得很机械。加了这个轻微的横向摆动泡泡的轨迹看起来会像被风吹着走有呼吸感。第三个是paintEvent里的QRadialGradient。每个泡泡不是用一个纯色圆形画出来的而是一个径向渐变——左上角更亮边缘变淡。这样做是为了让泡泡看起来有体积、有高光而不是一个个扁平的彩色圆片。效果上差别很大但代码只多花了几行。4. 这几个关键设计决定泡泡好不好看、卡不卡代码能跑起来只是第一步。很多人在网上复制类似的代码跑起来后发现卡、闪烁、点击位置不对往往是因为没有理解背后的几个设计决策。我把自己调试过程中最重要的经验拆开讲一下。4.1 为什么用QTimer加paintEvent重绘而不是用一大堆QLabel做动画最简单的做法是给每个泡泡创建一个QLabel控件然后移动它们的位置。我最初试过这个方案泡泡数量超过五六个以后窗口就开始有迟滞感。原因是每个QLabel都是独立的GUI控件移动它要触发布局和重绘数量一多代价就上去了。更好的做法是让每个泡泡只作为普通数据对象既不是控件也没有独立窗口由主窗口统一在paintEvent里把所有泡泡画出来。这样无论屏幕上飘着10个还是18个泡泡最终都只是一次性调用drawEllipse批量绘制性能和代码复杂度都可控。你看到的self.update()并不是立刻重绘而是通知Qt在下一帧统一处理这是Qt的优化机制频繁调用也不会导致闪烁。4.2 点击判定为什么用“距离公式”而不判断控件区域因为泡泡不是控件所以不能直接用QLabel.clicked之类的信号。我采用的方法是鼠标点击后拿到坐标(px, py)然后遍历当前所有泡泡计算它与泡泡圆心(b.x, b.y)之间的距离。如果距离小于等于泡泡半径就认为点中了。这个判定写起来非常简单dx * dx dy * dy r * r。不直接开平方是为了少一次sqrt计算18个泡泡遍历下来几乎没有开销。这个方案的优点是不受任何控件层级影响不管泡泡在程序里是什么形态只要你有圆心的位置数据就能判断。4.3 绘制顺序决定视觉层卡片要用独立QLabel垫在泡泡上面主窗口的paintEvent负责画背景和全部泡泡而点击后弹出的情话卡片用的是独立的QLabel。为什么要这样混着用因为如果卡片也画在paintEvent里它就只能存在一帧下一帧重绘就会被抹掉除非我额外维护一张“卡片队列”并且不断重绘复杂度会明显上升。用QLabel做卡片的好处是它是真实控件Qt会替你管理它的显示生命周期。card.show()和card.raise_()之后它会稳定地压在窗口内容之上。4秒后card.deleteLater()被调用控件自动销毁内存也不会积累。这里唯一的代价是QLabel不能加太花哨的动画但对我们这个场景完全够用。4.4 背景必须每次重绘否则会出现拖影在初版里我偷偷做过一个“优化”背景只画一次每次只画新泡泡指望旧泡泡消失后背景还能保持结果出现了严重的拖影。后来想明白屏幕重绘是一整块刷新的不会自动保留上一帧的像素所以必须每次在paintEvent里先画完整背景再画泡泡。背景渐变用QLinearGradient每次生成一次从下到上由深色过渡到玫瑰色。这个渐变每次重绘都会执行成本完全可以忽略因为颜色渐变只有一段线性插值比绘制几十个泡泡本身轻量得多。这里提醒一下不要试图用“只重绘变化区域”去优化Qt在帧率不高的时候这个优化意义不大还容易引入残影和撕裂感。5. 打包成exe让对方双击就能看见浪漫写代码的过程很愉快但真正让礼物成立的是最终能送到对方手里的那个单文件exe。如果你只是把valentine_bubbles.py发给一个完全没有Python环境的人他大概率会卡在“这是什么文件”“用什么打开”这步。所以必须用PyInstaller打包。5.1 打包步骤建议你在一个干净的虚拟环境里做。这样打包出来的文件不会把开发环境里无关依赖全部塞进来体积和稳定性都好很多。python -m venv .venv .venv\Scripts\activate pip install pyqt5 pyinstaller pyinstaller -F -w --name little_surprise valentine_bubbles.py参数解释-F表示生成单文件exe方便直接发送-w表示不弹出命令行黑窗口因为这是一个纯GUI程序--name指定输出文件名我故意用英文名避免某些系统或安全软件对中文文件名产生额外困扰打包完成后产物在dist目录下文件名是little_surprise.exe。如果你想加一个自定义图标可以在打包命令里加--iconheart.ico。但图标文件格式一定要是.ico直接改图片后缀名是不行的可以用在线转换工具或者Python的PIL库转一下。图标属于锦上添花不影响程序本身。5.2 打包后资源文件路径的坑打包完成后你会发现一件事messages.txt应该放在哪里很多人直接把txt和脚本放在一起打包后却读不到因为PyInstaller在-F模式下会把脚本和资源打进一个临时解压目录__file__指向的位置并不是exe所在目录。我在load_words()里用的是os.path.dirname(os.path.abspath(sys.argv[0]))也就是拿当前exe文件的路径来定位messages.txt。这样运行exe的时候它只会去exe所在的文件夹找同目录的messages.txt逻辑很直观。你修改词库时只需要在exe旁边新建一个文本文件不用重新打包。在打包前的调试阶段这段代码依然可以工作因为sys.argv[0]在普通脚本运行时会指向脚本本身路径。如果你想把词库放进脚本里面而不依赖外部文件项目也支持内置词库已经兜底。5.3 发送之前自己先过一遍测试清单我给这个项目设了一个简单的自测清单每次打包后发给别人之前至少花五分钟测一遍在没有安装Python的Windows虚拟机或另一台电脑上双击exe确认能正常打开点击泡泡确认字体显示正常没有方块、乱码靠近窗口四个边缘点击泡泡确认卡片不会被截断右键菜单里的暂停和退出都有效在系统显示缩放125%或150%下运行点击位置依然准确。前四条很容易测出来第五条容易被忽略。很多Qt程序在其他电脑上显示模糊或者错位就是因为没有开启高分屏支持。代码里QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True)这行必须在创建QApplication之前执行我把它放在if __name__ __main__:块的最顶行就是为了确保生效。6. 从通用模板变成专属礼物三个实用进阶方向基础版已经可以送人但如果你想让礼物更特别一点这里有三个方向我实测过难度从低到高可根据自己的时间选。6.1 外部词库编辑器20秒换一批新情话我前面提到的messages.txt就是最轻量的“外置配置”。你可以在exe旁边新建一个messages.txt编码存成UTF-8每行一句话程序启动后会直接使用。这个方案的价值在于当你灵感来了、或者想根据日期临时加一句“第520天快乐”之类的话不用重新打包打开txt改一行保存就行。唯一要注意的是编码问题。Windows自带记事本在保存时可能会带BOM头第一行的第一句前面会多个看不见的字符。我在读取时没有做utf-8-sig处理如果你碰到第一句文字前有小黑点就用其他编辑器保存成“UTF-8无BOM”格式。这个小坑我在给朋友做礼物的时踩过一次印象很深。6.2 点击泡泡后显示“在一起第几天”这是一个成本很低但效果很炸裂的定制。只需要在show_card方法计算一下当前日期和约定日期的差值拼进显示文字里。import datetime start_day datetime.date(2022, 2, 14) days (datetime.date.today() - start_day).days card_text f{b.word}\n\n我们已经在一起 {days} 天把这段逻辑放在show_card的card.setText之前会得到一行额外的日子提醒。虽然只是几行代码但对收礼物的人来说这种细节远比花哨特效动人。如果你用外部词库还可以保留几个特殊词命中后自动追加天数元素更丰富。6.3 “彩蛋泡泡”随机出现的小惊喜我还做过一个版本在词库里故意放一个极少出现的关键词当泡泡文字是这句时点击后不弹普通卡片而是在屏幕中央显示一张照片或者二维码海报。实现方式是用新的QLabel配合QPixmap加载图片把原来纯文字的卡片替换掉。原理并不复杂在show_card里判断语句是否等于预设彩蛋词如果是就换成图片。照片文件可以放当前目录打包后也可以作为外部资源随时更换。要注意的是二维码或照片尺寸不要设计得太大否则在小窗口里显示会超出边界。这种“只有特定泡泡才有的隐藏内容”非常适合浪漫场景也适合做纪念日惊喜。7. 这些坑我提前帮你踩过了最后集中说一下最容易让人挫败的细节。这些坑我在开发和打包过程中都真实遇到过每一条都能省下你两三个小时的排查时间。第一个坑第一次打包出来的exe双击后没有任何反应也没有窗口。排查后发现是打包时加了-w程序一旦在启动阶段报错错误信息不会显示在任何地方看起来就像“死了”。解决办法是先不加-w重新打包一次让控制台窗口暴露出来看到真正的报错再针对性修复。记住不要一开始就追求“无黑窗口”先能看到错误再隐藏错误。第二个坑中文显示成方块。如果你用的是Windows把字体设置成微软雅黑基本就不会有问题。但在某些精简版系统或PE环境下系统中文字体被精简掉了这时需要把字体文件放在exe同目录并在代码里用QFontDatabase.addApplicationFont(xxx.ttf)动态加载。不夸张地说字体问题遇到一次之后你会养成“永远不依赖系统默认字体”的习惯。第三个坑卡片文字被窗口截断。很多人以为把卡片坐标直接设置成点击位置就没问题实际上一句话长一点卡片会超出窗口边界看不见。我在show_card里加了边界修正left max(8, min(x - w // 2, self.width() - w - 8)) top max(8, min(y - h - 20, self.height() - h - 8))这行的作用是如果卡片预定位置在窗口外就强制拉回到窗口内并且留出8像素的安全边距。这个细节能明显提升体验尤其是点击窗口边缘的泡泡时。第四个坑高分屏缩放导致点击错位。如果你在系统设置里把显示缩放调成125%或者150%再运行这个程序会发现鼠标点击的位置和泡泡实际位置对不上。这跟Qt的坐标体系和全局DPI缩放有关。解决方式就是我前面说的在创建QApplication之前设置Qt.AA_EnableHighDpiScaling。注意这行代码的位置很重要放在创建之后是无效的。第五个坑杀毒软件误报。PyInstaller打包出来的exe在一些杀毒软件眼里天然可疑因为它们没有数字签名又是“单文件、释放临时资源”的运行方式。我遇到过朋友反馈exe被电脑直接删掉的情况。目前没有100%一劳永逸的办法但有几个缓解手段尽量在配置好的干净环境打包文件名不要带“破解”“外挂”等敏感字眼如果对方电脑误删让他隔离区恢复并添加信任即可。这个属于打包工具生态的通病跟你代码本身是否安全没有关系。第六个坑不要只发代码文件。很多人把valentine_bubbles.py直接发给对方以为对方能自己跑。实际上对方大概率不会安装Python也看不懂报错。所以要送就送exe或者退一步送一个包含bat启动脚本的压缩包。这个项目真正的交付物是一个可执行文件不是一堆源码。源码只是你实现它的过程。我在实际调试中还有一个很深的体会技术上的东西做得再好如果收到礼物的人连续碰壁三次起不来程序好感度会被消磨光。所以千万不要高估对方的“动手能力”也不要高估杀毒软件的“耐心”。你替对方把环境、交互、边界问题都处理好才是最用心的礼物。如果做完这个项目你还想继续折腾同一个代码框架可以改成节日祝福壁纸、桌面倒计时、会议签到彩蛋等版本。只要把握住“一个窗口、几个浮动圆形、点击显示信息”这个核心结构扩展空间其实挺大的。现在你可以把电脑上的代码打包好亲手点开第一个泡泡了。

相关新闻

激光与电火花加工仿真:从热源到熔池流动的多物理场建模实践

激光与电火花加工仿真:从热源到熔池流动的多物理场建模实践

激光打孔看着简单——一束光打下去,材料上多了个眼。但你要是想提前算出来这个眼长什么样,事情立刻变复杂了。激光打孔时熔融金属会从孔口飞溅出来,孔壁上会留下重铸层,入口边缘还有一圈毛刺;电火花加工那边更热闹&…

2026/10/11 3:59:54 阅读更多 →
Java面试翻车现场:HashMap、线程池、JVM深度拆解

Java面试翻车现场:HashMap、线程池、JVM深度拆解

“严肃面试官 vs 搞笑水货程序员谢飞机(本名王大瓜)——互联网大厂 Java 面试实录与技术拆解”,光看这个标题你可能觉得是个段子,但我在现场的感觉是:这简直就是一场喜剧外壳下的技术解剖课。谢飞机,简历上…

2026/10/11 3:58:54 阅读更多 →
RT-Thread—STM32—环境搭建

RT-Thread—STM32—环境搭建

RT-Thread——STM32——环境搭建 概述 本教程主要根据官方推荐的教程进行环境搭建,但是在打包方面按照自己的习惯进行了打包。 RT-Thread官网有特别详细的教程,这儿就不详细说明RT-Thread官网 软件准备 MDK528a (Keil5)CubeMx_v5-2-0STM32CubeMx的支持…

2026/10/11 3:58:54 阅读更多 →

最新新闻

Wand-Enhancer 完整指南:4 步免费解锁 WeMod Wand Pro 与手机远程面板

Wand-Enhancer 完整指南:4 步免费解锁 WeMod Wand Pro 与手机远程面板

Wand-Enhancer 完整指南:4 步免费解锁 WeMod Wand Pro 与手机远程面板 【免费下载链接】Wand-Enhancer Advanced UX and interoperability extension for Wand (WeMod) app 项目地址: https://gitcode.com/GitHub_Trending/we/Wand-Enhancer Wand-Enhancer 是…

2026/10/11 4:42:20 阅读更多 →
Python控制Arduino与树莓派:串口、Firmata与GPIO实战指南

Python控制Arduino与树莓派:串口、Firmata与GPIO实战指南

前阵子有个做智能家居的朋友问我,想用Python控制Arduino或树莓派,感觉网上资料很散,不知道该从哪条路入门。这个问题我太熟了,刚接触硬件时我也被这两种设备搞晕过:Arduino是微控制器,跑的是C;树…

2026/10/11 4:42:20 阅读更多 →
COSCon‘25 RISC-V论坛议程拆解:生态加速信号与开发者参与路径

COSCon‘25 RISC-V论坛议程拆解:生态加速信号与开发者参与路径

看到 COSCon‘25 RISC-V 开源论坛的议程正式发布,我第一反应不是“又有会议”,而是松了口气。关注 RISC-V 生态的朋友都知道,这几年“指令集开放”“生态加速”这些说法几乎被聊烂了,但真正落到会议议程上的系统性安排&#xff0c…

2026/10/11 4:42:19 阅读更多 →
体育馆人流量监测系统设计与部署实战:从选型到上线

体育馆人流量监测系统设计与部署实战:从选型到上线

前阵子接了一个不算特别前沿、但相当磨人的项目:给某座中型体育馆设计并部署一套基于物联网的人流量监测系统。体育馆的场地运营方最初的需求很简单,就一句话:"我想知道现在馆里有多少人,别再靠保安掐着对讲机报数了。"…

2026/10/11 4:42:19 阅读更多 →
机器学习入门指南:核心算法、复杂度与落地场景全解析

机器学习入门指南:核心算法、复杂度与落地场景全解析

如果你点进这篇文章,大概率和我当年一样,被“机器学习”这四个字吓住过。我做了好几年机器学习相关的工作,带过不少零基础的朋友(甚至真有一位“太奶”级别的长辈问我:这玩意儿是不是跟算命差不多)&#xf…

2026/10/11 4:42:19 阅读更多 →
如何从GitHub日榜中筛选出真正有价值的开源项目

如何从GitHub日榜中筛选出真正有价值的开源项目

每天早上打开 GitHub Trending 刷一遍热榜项目,已经成了我这几年雷打不动的固定动作。2026-10-08 这份日榜我反复看了两遍,最直观的感受是:与前一周相比,榜单前排的换手率明显加大了——头一天还停在第三名的“某Agent协作框架”直…

2026/10/11 4:41:19 阅读更多 →

日新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/11 0:00:27 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/11 0:00:27 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 10:38:42 阅读更多 →