桌面宠物的各种动画效果,可以看作是由一个个GIF动图拼接而成,我们需要准备多组GIF动图来实现桌面宠物的动作切换。

最好选取是白底的GIF动图。

pr在导出的时候选择动画GIF可以直接导出GIF动图。
当然了想要白底就需要自已用“蒙版”和画笔工具自己抠图了。
ps会高级一点,首先点击最上方的窗口,再点击时间轴,在下方显示出的时间轴的最右边的加号可以添加你想要添加的图片。图层右边可以选择删除背景。

然后选择最上方的文件,选择导出,选择导出为web所用格式旧版,即可


① 百度:“制作GIF动图”
② 百度 “GIF动图资源”
你想要的角色人物素材都在这里!最实用的2d游戏素材! - 知乎

项目的目录结构整体如下:main.py为主程序代码。

normal下的GIF图是宠物平常会随机切换的动作GIF图, click下面的GIF图是点击宠物之后的宠物动作的GIF图

dialog.txt 记录了宠物的对话信息

tigerIcon.jpg是缩小到托盘后托盘图标的图片

os包用于加载文件,sys包用于退出程序,random包用于程序中一些需要调用随机数的操作。其他的三个包则是用于实现桌面宠物的基础。
import os
import sys
import random
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
if __name__ == '__main__':
# 创建了一个QApplication对象,对象名为app,带两个参数argc,argv
# 所有的PyQt5应用必须创建一个应用(Application)对象。sys.argv参数是一个来自命令行的参数列表。
app = QApplication(sys.argv)
# 窗口组件初始化
pet = DesktopPet()
# 1. 进入时间循环;
# 2. wait,直到响应app可能的输入;
# 3. QT接收和处理用户及系统交代的事件(消息),并传递到各个窗口;
# 4. 程序遇到exit()退出时,机会返回exec()的值。
sys.exit(app.exec_())
整个运行流程为:
(1)通过self.init():实现窗体的初始化,宠物的GIF图在这个窗体中播放。
(2)通过self.initPall():配置托盘化
(3)通过self.initPetImage():将宠物的静态GIF资源,包括对话和GIF动图进行加载
(4)通过self.petNormalAction():实现宠物随机切换动作和语句的功能
class DesktopPet(QWidget):
def __init__(self, parent=None, **kwargs):
super(DesktopPet, self).__init__(parent)
# 窗体初始化
self.init()
# 托盘化初始
self.initPall()
# 宠物静态gif图加载
self.initPetImage()
# 宠物正常待机,实现随机切换动作
self.petNormalAction()
① 加载显示GIF动图的窗体,通过函数init实现,其代码配置如下:
这几句的作用是对展示宠物的窗体进行一些初步的设置,使得白色GIF图能够去掉背景的白色,将GIF图透明的展示出来
# 窗体初始化
def init(self):
# 初始化
# 设置窗口属性:窗口无标题栏且固定在最前面
# FrameWindowHint:无边框窗口
# WindowStaysOnTopHint: 窗口总显示在最上面
# SubWindow: 新窗口部件是一个子窗口,而无论窗口部件是否有父窗口部件
# https://blog.csdn.net/kaida1234/article/details/79863146
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.SubWindow)
# setAutoFillBackground(True)表示的是自动填充背景,False为透明背景
self.setAutoFillBackground(False)
# 窗口透明,窗体空间不透明
self.setAttribute(Qt.WA_TranslucentBackground, True)
# 重绘组件、刷新
self.repaint()
② 实现能托盘显示的功能,通过函数initPall实现,其代码配置如下:
主要有下面这几个操作:
(1)读取静态图片资源设置托盘化的图标

(2)设置托盘化图片点击右键显示的菜单,并对这些菜单的点击操作进行设置

流程代码如下:
# 托盘化设置初始化
def initPall(self):
# 导入准备在托盘化显示上使用的图标
icons = os.path.join('tigerIcon.jpg')
# 设置右键显示最小化的菜单项
# 菜单项退出,点击后调用quit函数
quit_action = QAction('退出', self, triggered=self.quit)
# 设置这个点击选项的图片
quit_action.setIcon(QIcon(icons))
# 菜单项显示,点击后调用showing函数
showing = QAction(u'显示', self, triggered=self.showwin)
# 新建一个菜单项控件
self.tray_icon_menu = QMenu(self)
# 在菜单栏添加一个无子菜单的菜单项‘退出’
self.tray_icon_menu.addAction(quit_action)
# 在菜单栏添加一个无子菜单的菜单项‘显示’
self.tray_icon_menu.addAction(showing)
# QSystemTrayIcon类为应用程序在系统托盘中提供一个图标
self.tray_icon = QSystemTrayIcon(self)
# 设置托盘化图标
self.tray_icon.setIcon(QIcon(icons))
# 设置托盘化菜单项
self.tray_icon.setContextMenu(self.tray_icon_menu)
# 展示
self.tray_icon.show()
其中‘退出’项涉及到的函数代码如下:
# 退出操作,关闭程序
def quit(self):
self.close()
sys.exit()
其中‘显示’项涉及到的函数代码如下:
# 显示宠物
def showwin(self):
# setWindowOpacity()设置窗体的透明度,通过调整窗体透明度实现宠物的展示和隐藏
self.setWindowOpacity(1)
③ 宠物静态资源的加载,通过函数initPetImage实现,其代码配置如下:
静态资源的加载主要涉及两个部分,对话框内容的加载和图片内容的加载。
# 宠物静态gif图加载
def initPetImage(self):
# 对话框定义
self.talkLabel = QLabel(self)
# 对话框样式设计
self.talkLabel.setStyleSheet("font:15pt '楷体';border-width: 1px;color:blue;")
# 定义显示图片部分
self.image = QLabel(self)
# QMovie是一个可以存放动态视频的类,一般是配合QLabel使用的,可以用来存放GIF动态图
self.movie = QMovie("normal/normal1.gif")
# 设置标签大小
self.movie.setScaledSize(QSize(200, 200))
# 将Qmovie在定义的image中显示
self.image.setMovie(self.movie)
self.movie.start()
self.resize(1024, 1024)
# 调用自定义的randomPosition,会使得宠物出现位置随机
self.randomPosition()
# 展示
self.show()
# https://new.qq.com/rain/a/20211014a002rs00
# 将宠物正常待机状态的动图放入pet1中
self.pet1 = []
for i in os.listdir("normal"):
self.pet1.append("normal/" + i)
# 将宠物正常待机状态的对话放入pet2中
self.dialog = []
# 读取目录下dialog文件
with open("dialog.txt", "r") as f:
text = f.read()
# 以\n 即换行符为分隔符,分割放进dialog中
self.dialog = text.split("\n")
其中我们希望宠物出现的位置是随机的而不是固定的,那么便通过 randomPosition()实现宠物出现位置的随机。
# 宠物随机位置
def randomPosition(self):
# screenGeometry()函数提供有关可用屏幕几何的信息
screen_geo = QDesktopWidget().screenGeometry()
# 获取窗口坐标系
pet_geo = self.geometry()
width = (screen_geo.width() - pet_geo.width()) * random.random()
height = (screen_geo.height() - pet_geo.height()) * random.random()
self.move(width, height)
④ 宠物正常待机,实现随机切换动作,对话框通过函数petNormalAction实现,其代码配置如下
这里通过QTimer实现定时操作,到达设置的时间即调用相关的函数。其中condition为标识宠物状态的flag,0为平常状态,1为点击状态,这个状态可按照自己的喜好拓展。talk_condition同理,为标识宠物对话状态的flag。
# 宠物正常待机动作
def petNormalAction(self):
# 每隔一段时间做个动作
# 定时器设置
self.timer = QTimer()
# 时间到了自动执行
self.timer.timeout.connect(self.randomAct)
# 动作时间切换设置
self.timer.start(3000)
# 宠物状态设置为正常
self.condition = 0
# 每隔一段时间切换对话
self.talkTimer = QTimer()
self.talkTimer.timeout.connect(self.talk)
self.talkTimer.start(3000)
# 对话状态设置为常态
self.talk_condition = 0
# 宠物对话框
self.talk()
其中,通过randomAct实现宠物动作的随机切换,通过talk实现对话框内容的切换,其代码如下:
self.pet1和self.dialog在初始化的时候即定义了。这里可以按照自己的喜好进行拓展,用多个if-else if实现多种状态的切换和定义,增加一些喂食,玩耍动作等。
# 随机动作切换
def randomAct(self):
# condition记录宠物状态,宠物状态为0时,代表正常待机
if not self.condition:
# 随机选择装载在pet1里面的gif图进行展示,实现随机切换
self.movie = QMovie(random.choice(self.pet1))
# 宠物大小
self.movie.setScaledSize(QSize(200, 200))
# 将动画添加到label中
self.image.setMovie(self.movie)
# 开始播放动画
self.movie.start()
# condition不为0,转为切换特有的动作,实现宠物的点击反馈
# 这里可以通过else-if语句往下拓展做更多的交互功能
else:
# 读取特殊状态图片路径
self.movie = QMovie("./click/click.gif")
# 宠物大小
self.movie.setScaledSize(QSize(200, 200))
# 将动画添加到label中
self.image.setMovie(self.movie)
# 开始播放动画
self.movie.start()
# 宠物状态设置为正常待机
self.condition = 0
self.talk_condition = 0
# 宠物对话框行为处理
def talk(self):
if not self.talk_condition:
# talk_condition为0则选取加载在dialog中的语句
self.talkLabel.setText(random.choice(self.dialog))
# 设置样式
self.talkLabel.setStyleSheet(
"font: bold;"
"font:25pt '楷体';"
"color:white;"
"background-color: white"
"url(:/)"
)
# 根据内容自适应大小
self.talkLabel.adjustSize()
else:
# talk_condition为1显示为别点我,这里同样可以通过if-else-if来拓展对应的行为
self.talkLabel.setText("别点我")
self.talkLabel.setStyleSheet(
"font: bold;"
"font:25pt '楷体';"
"color:white;"
"background-color: white"
"url(:/)"
)
self.talkLabel.adjustSize()
# 设置为正常状态
self.talk_condition = 0
⑤ 实现能够拖动宠物,通过多个自带函数实现,其代码配置如下:
实现宠物的拖动主要通过三个函数实现,mouserPressEvent负责在鼠标点击判断其是否在宠物窗口上,如果在则将宠物和鼠标的位置绑定,并执行点击改变宠物GIF图和对话框的操作。
mouseMoveEvent实现按下后宠物跟着鼠标移动
mouseReleaseEvent将之前的锁定取消
# 鼠标左键按下时, 宠物将和鼠标位置绑定
def mousePressEvent(self, event):
# 更改宠物状态为点击
self.condition = 1
# 更改宠物对话状态
self.talk_condition = 1
# 即可调用对话状态改变
self.talk()
# 即刻加载宠物点击动画
self.randomAct()
if event.button() == Qt.LeftButton:
self.is_follow_mouse = True
# globalPos() 事件触发点相对于桌面的位置
# pos() 程序相对于桌面左上角的位置,实际是窗口的左上角坐标
self.mouse_drag_pos = event.globalPos() - self.pos()
event.accept()
# 拖动时鼠标图形的设置
self.setCursor(QCursor(Qt.OpenHandCursor))
# 鼠标移动时调用,实现宠物随鼠标移动
def mouseMoveEvent(self, event):
# 如果鼠标左键按下,且处于绑定状态
if Qt.LeftButton and self.is_follow_mouse:
# 宠物随鼠标进行移动
self.move(event.globalPos() - self.mouse_drag_pos)
event.accept()
# 鼠标释放调用,取消绑定
def mouseReleaseEvent(self, event):
self.is_follow_mouse = False
# 鼠标图形设置为箭头
self.setCursor(QCursor(Qt.ArrowCursor))
⑥ 实现宠物右键点击具有交互功能,通过函数contextMenuEvent实现,其代码配置如下:
退出操作通过 qApp.quit()实现,直接退出相应的QT程序。
隐藏操作则通过self.setWindowOpacity(0)实现,这个可控制窗口的透明度。
# 宠物右键点击交互
def contextMenuEvent(self, event):
# 定义菜单
menu = QMenu(self)
# 定义菜单项
quitAction = menu.addAction("退出")
hide = menu.addAction("隐藏")
# 使用exec_()方法显示菜单。从鼠标右键事件对象中获得当前坐标。mapToGlobal()方法把当前组件的相对坐标转换为窗口(window)的绝对坐标。
action = menu.exec_(self.mapToGlobal(event.pos()))
# 点击事件为退出
if action == quitAction:
qApp.quit()
# 点击事件为隐藏
if action == hide:
# 通过设置透明度方式隐藏宠物
self.setWindowOpacity(0)

⑦ 鼠标移到宠物上的时候显示为闭合的手
# 鼠标移进时调用
def enterEvent(self, event):
# 设置鼠标形状 Qt.ClosedHandCursor 非指向手
self.setCursor(Qt.ClosedHandCursor)
import os
import sys
import random
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class DesktopPet(QWidget):
def __init__(self, parent=None, **kwargs):
super(DesktopPet, self).__init__(parent)
# 窗体初始化
self.init()
# 托盘化初始
self.initPall()
# 宠物静态gif图加载
self.initPetImage()
# 宠物正常待机,实现随机切换动作
self.petNormalAction()
# 窗体初始化
def init(self):
# 初始化
# 设置窗口属性:窗口无标题栏且固定在最前面
# FrameWindowHint:无边框窗口
# WindowStaysOnTopHint: 窗口总显示在最上面
# SubWindow: 新窗口部件是一个子窗口,而无论窗口部件是否有父窗口部件
# https://blog.csdn.net/kaida1234/article/details/79863146
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.SubWindow)
# setAutoFillBackground(True)表示的是自动填充背景,False为透明背景
self.setAutoFillBackground(False)
# 窗口透明,窗体空间不透明
self.setAttribute(Qt.WA_TranslucentBackground, True)
# 重绘组件、刷新
self.repaint()
# 托盘化设置初始化
def initPall(self):
# 导入准备在托盘化显示上使用的图标
icons = os.path.join('tigerIcon.jpg')
# 设置右键显示最小化的菜单项
# 菜单项退出,点击后调用quit函数
quit_action = QAction('退出', self, triggered=self.quit)
# 设置这个点击选项的图片
quit_action.setIcon(QIcon(icons))
# 菜单项显示,点击后调用showing函数
showing = QAction(u'显示', self, triggered=self.showwin)
# 新建一个菜单项控件
self.tray_icon_menu = QMenu(self)
# 在菜单栏添加一个无子菜单的菜单项‘退出’
self.tray_icon_menu.addAction(quit_action)
# 在菜单栏添加一个无子菜单的菜单项‘显示’
self.tray_icon_menu.addAction(showing)
# QSystemTrayIcon类为应用程序在系统托盘中提供一个图标
self.tray_icon = QSystemTrayIcon(self)
# 设置托盘化图标
self.tray_icon.setIcon(QIcon(icons))
# 设置托盘化菜单项
self.tray_icon.setContextMenu(self.tray_icon_menu)
# 展示
self.tray_icon.show()
# 宠物静态gif图加载
def initPetImage(self):
# 对话框定义
self.talkLabel = QLabel(self)
# 对话框样式设计
self.talkLabel.setStyleSheet("font:15pt '楷体';border-width: 1px;color:blue;")
# 定义显示图片部分
self.image = QLabel(self)
# QMovie是一个可以存放动态视频的类,一般是配合QLabel使用的,可以用来存放GIF动态图
self.movie = QMovie("normal/normal1.gif")
# 设置标签大小
self.movie.setScaledSize(QSize(200, 200))
# 将Qmovie在定义的image中显示
self.image.setMovie(self.movie)
self.movie.start()
self.resize(1024, 1024)
# 调用自定义的randomPosition,会使得宠物出现位置随机
self.randomPosition()
# 展示
self.show()
# https://new.qq.com/rain/a/20211014a002rs00
# 将宠物正常待机状态的动图放入pet1中
self.pet1 = []
for i in os.listdir("normal"):
self.pet1.append("normal/" + i)
# 将宠物正常待机状态的对话放入pet2中
self.dialog = []
# 读取目录下dialog文件
with open("dialog.txt", "r") as f:
text = f.read()
# 以\n 即换行符为分隔符,分割放进dialog中
self.dialog = text.split("\n")
# 宠物正常待机动作
def petNormalAction(self):
# 每隔一段时间做个动作
# 定时器设置
self.timer = QTimer()
# 时间到了自动执行
self.timer.timeout.connect(self.randomAct)
# 动作时间切换设置
self.timer.start(3000)
# 宠物状态设置为正常
self.condition = 0
# 每隔一段时间切换对话
self.talkTimer = QTimer()
self.talkTimer.timeout.connect(self.talk)
self.talkTimer.start(3000)
# 对话状态设置为常态
self.talk_condition = 0
# 宠物对话框
self.talk()
# 随机动作切换
def randomAct(self):
# condition记录宠物状态,宠物状态为0时,代表正常待机
if not self.condition:
# 随机选择装载在pet1里面的gif图进行展示,实现随机切换
self.movie = QMovie(random.choice(self.pet1))
# 宠物大小
self.movie.setScaledSize(QSize(200, 200))
# 将动画添加到label中
self.image.setMovie(self.movie)
# 开始播放动画
self.movie.start()
# condition不为0,转为切换特有的动作,实现宠物的点击反馈
# 这里可以通过else-if语句往下拓展做更多的交互功能
else:
# 读取特殊状态图片路径
self.movie = QMovie("./click/click.gif")
# 宠物大小
self.movie.setScaledSize(QSize(200, 200))
# 将动画添加到label中
self.image.setMovie(self.movie)
# 开始播放动画
self.movie.start()
# 宠物状态设置为正常待机
self.condition = 0
self.talk_condition = 0
# 宠物对话框行为处理
def talk(self):
if not self.talk_condition:
# talk_condition为0则选取加载在dialog中的语句
self.talkLabel.setText(random.choice(self.dialog))
# 设置样式
self.talkLabel.setStyleSheet(
"font: bold;"
"font:25pt '楷体';"
"color:white;"
"background-color: white"
"url(:/)"
)
# 根据内容自适应大小
self.talkLabel.adjustSize()
else:
# talk_condition为1显示为别点我,这里同样可以通过if-else-if来拓展对应的行为
self.talkLabel.setText("别点我")
self.talkLabel.setStyleSheet(
"font: bold;"
"font:25pt '楷体';"
"color:white;"
"background-color: white"
"url(:/)"
)
self.talkLabel.adjustSize()
# 设置为正常状态
self.talk_condition = 0
# 退出操作,关闭程序
def quit(self):
self.close()
sys.exit()
# 显示宠物
def showwin(self):
# setWindowOpacity()设置窗体的透明度,通过调整窗体透明度实现宠物的展示和隐藏
self.setWindowOpacity(1)
# 宠物随机位置
def randomPosition(self):
screen_geo = QDesktopWidget().screenGeometry()
pet_geo = self.geometry()
width = (screen_geo.width() - pet_geo.width()) * random.random()
height = (screen_geo.height() - pet_geo.height()) * random.random()
self.move(width, height)
# 鼠标左键按下时, 宠物将和鼠标位置绑定
def mousePressEvent(self, event):
# 更改宠物状态为点击
self.condition = 1
# 更改宠物对话状态
self.talk_condition = 1
# 即可调用对话状态改变
self.talk()
# 即刻加载宠物点击动画
self.randomAct()
if event.button() == Qt.LeftButton:
self.is_follow_mouse = True
# globalPos() 事件触发点相对于桌面的位置
# pos() 程序相对于桌面左上角的位置,实际是窗口的左上角坐标
self.mouse_drag_pos = event.globalPos() - self.pos()
event.accept()
# 拖动时鼠标图形的设置
self.setCursor(QCursor(Qt.OpenHandCursor))
# 鼠标移动时调用,实现宠物随鼠标移动
def mouseMoveEvent(self, event):
# 如果鼠标左键按下,且处于绑定状态
if Qt.LeftButton and self.is_follow_mouse:
# 宠物随鼠标进行移动
self.move(event.globalPos() - self.mouse_drag_pos)
event.accept()
# 鼠标释放调用,取消绑定
def mouseReleaseEvent(self, event):
self.is_follow_mouse = False
# 鼠标图形设置为箭头
self.setCursor(QCursor(Qt.ArrowCursor))
# 鼠标移进时调用
def enterEvent(self, event):
# 设置鼠标形状 Qt.ClosedHandCursor 非指向手
self.setCursor(Qt.ClosedHandCursor)
# 宠物右键点击交互
def contextMenuEvent(self, event):
# 定义菜单
menu = QMenu(self)
# 定义菜单项
quitAction = menu.addAction("退出")
hide = menu.addAction("隐藏")
# 使用exec_()方法显示菜单。从鼠标右键事件对象中获得当前坐标。mapToGlobal()方法把当前组件的相对坐标转换为窗口(window)的绝对坐标。
action = menu.exec_(self.mapToGlobal(event.pos()))
# 点击事件为退出
if action == quitAction:
qApp.quit()
# 点击事件为隐藏
if action == hide:
# 通过设置透明度方式隐藏宠物
self.setWindowOpacity(0)
if __name__ == '__main__':
# 创建了一个QApplication对象,对象名为app,带两个参数argc,argv
# 所有的PyQt5应用必须创建一个应用(Application)对象。sys.argv参数是一个来自命令行的参数列表。
app = QApplication(sys.argv)
# 窗口组件初始化
pet = DesktopPet()
# 1. 进入时间循环;
# 2. wait,直到响应app可能的输入;
# 3. QT接收和处理用户及系统交代的事件(消息),并传递到各个窗口;
# 4. 程序遇到exit()退出时,机会返回exec()的值。
sys.exit(app.exec_())
pip install pyinstaller
如果提示黄色提示pip版本问题,照着上面的提示修改即可
进入打开cmd命令行,进入项目目录,输入命令
pyinstaller -F -w main.py

打包完成后,在生成的dist里面可以看到main.exe文件

这里因为我自己的原因,需要将main.exe放到主目录下才可正常运行

链接:https://pan.baidu.com/s/1YYXzGpmCJkz43tYuki1wFQ
提取码:3gkw

DeskTopPetEXE为带打包好的文件。
DeskTopPet是打包前的文件。
写之前挺开心的,写的时候也挺开心的,写完之后就有点索然无味了。用python做一个简单的桌面宠物,我看到的方法除了我参考的这种加载GIF图外:
Python 玩出花儿,把罗小黑养在自己桌面_AI科技大本营的博客-CSDN博客
还有一种通过加载图片帧的方式实现
Python实现桌面宠物_hxxjxw的博客-CSDN博客_python桌面宠物
这种通过图片帧的加载实现,需要编写一个自定义配置类cfg.py,很多人也不把这个东西代码给出来:
'''配置文件'''
ROOT_DIR = 'resources'
ACTION_DISTRIBUTION = [['1', '2', '3'],
['4', '5', '6', '7', '8', '9', '10', '11'],
['12', '13', '14'],
['15', '16', '17', '18']]
PET_ACTIONS_MAP = {'pet_1': ACTION_DISTRIBUTION}
for i in range(1, 4):
PET_ACTIONS_MAP.update({'pet_%s' % i: ACTION_DISTRIBUTION})
这种方式宠物动作的实现,是根据上面这个配置文件进行配置的,比如[1,2,3]就代表这个pet_1文件夹下对应1,2,3号图片组成一个动作。我看到有人直接把这个当作一个动作赋值给宠物,然后图片就会莫名鬼畜。
纯粹是因为无聊写着玩的,下次再试试能不能弄个3D的🙂
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
从MB升级到新的MBP后,Apple的迁移助手没有移动我的gem。我这次是通过macports安装rubygems,希望在下次升级时避免这种情况。有什么我应该注意的陷阱吗? 最佳答案 如果你想把你的gems安装在你的主目录中(在传输过程中应该复制过来,作为一个附带的好处,会让你以你自己的身份运行geminstall,而不是root),将gemhome:键设置为您在~/.gemrc中的主目录中的路径. 关于通过MacPorts的RubyGems是个好主意吗?,我们在StackOverf
当我执行>rvminstall1.9.2时一切顺利。然后我做>rvmuse1.9.2也很顺利。但是当涉及到ruby-v时..sam@sjones:~$rvminstall1.9.2/home/sam/.rvm/rubies/ruby-1.9.2-p136,thismaytakeawhiledependingonyourcpu(s)...ruby-1.9.2-p136-#fetchingruby-1.9.2-p136-#downloadingruby-1.9.2-p136,thismaytakeawhiledependingonyourconnection...%Total%Rece
当谈到运行时自省(introspection)和动态代码生成时,我认为ruby没有任何竞争对手,可能除了一些lisp方言。前几天,我正在做一些代码练习来探索ruby的动态功能,我开始想知道如何向现有对象添加方法。以下是我能想到的3种方法:obj=Object.new#addamethoddirectlydefobj.new_method...end#addamethodindirectlywiththesingletonclassclass这只是冰山一角,因为我还没有探索instance_eval、module_eval和define_method的各种组合。是否有在线/离线资