Google SketchUp 关闭文件 [英] Google SketchUp close file

查看:30
本文介绍了Google SketchUp 关闭文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Google SketchUp 的 Ruby API一个函数,open_file,但我找不到 close_file 函数.由于我要批量处理很多文件,我想在继续下一个文件之前关闭每个文件,否则程序会因内存耗尽而崩溃.

以编程方式关闭 SketchUp 文件的最佳方法是什么?

我使用的是 Mac OS X 并且愿意使用 AppleScript 函数来通知窗口关闭.

编辑

我正在考虑一些迄今为止被证明无效的方法.

  1. 使用 appscript Ruby gem,如这个问题中所述.这里的问题是我无法让 SketchUp 识别我安装的 gem.
  2. 同样,我正在尝试使用 osascript(一个从 shell 执行 AppleScripts 的 bash 程序)来关闭窗口.也就是说,我使用以下方法之一从 SketchUp 的 Ruby 控制台窗口调用 shell:

    %x[osascript -e '告诉应用程序SketchUp"关闭窗口 1']

    %x[osascript -e '告诉应用程序SketchUp"关闭窗口 1' &]

    %x[osascript -e '告诉应用程序SketchUp"关闭每个窗口']

    %x[osascript -e '告诉应用程序SketchUp"关闭每个窗口' &]

    每当我尝试第二种方法时,SketchUp 就会冻结.但是,当我从 IRB 或直接从 SketchUp 外部的 Bash 提示符执行这些命令中的任何时,我得到了所需的行为:模型窗口关闭(顺便说一句,Ruby 控制台窗口保持打开状态,很好).

  3. 有一个主脚本来启动一个从脚本来处理每个模型.从站将在主站等待时在 Google SketchUp 程序中运行.当slave完成后,它向master发出信号,master关闭SketchUp文件.为了进行这种进程间通信,我尝试使用 drb.但是,当我尝试在 SketchUp 中要求 drb 时,我收到以下消息:

<块引用>

错误: LoadError: (eval):5:in 'require': 没有要加载的文件 -- drb

编辑 2

有一个单独的进程持续运行以在收到信号时使用 AppleScript 关闭 Google Sketchup 窗口是很笨拙的,原因有很多.首先,必须有一个专门用于关闭 Sketchup 窗口的单独过程是很丑陋的.其次,与外部脚本通信的唯一有效方法是通过创建文件,这是一种浪费并且磁盘访问可能会减慢速度.

然而,最严重的问题是 Sketchup 响应 AppleScript 命令的速度很慢.我有一个在 Sketchup 中运行的计算密集型脚本,它似乎使 AppleScript 响应挨饿,这意味着 osascript 在窗口关闭之前超时.Sketchup 仅在 Sketchup 中出现对话框提示暂停执行我的计算密集型脚本时才会响应 AppleScript.

编辑 3

我修改了我的 close_file 函数以通过显示一个对话框来暂停脚本的执行.这实质上产生了当前线程并允许响应 AppleScript 命令的线程执行:

def close_file()f = '/temp/mutex.txt' # 为了更好的控制,对每个要关闭的窗口使用不同的互斥锁File.new(f, 'w').closeresult = UI.messagebox "当窗口关闭时单击确定."结尾

然后,通过 AppleScript 关闭窗口的单独 ruby​​ 脚本还必须在对话框中单击确定".这样做的 AppleScript 是:

告诉应用程序系统事件"告诉进程SketchUp"将最前面设置为 true击键返回结束告诉结束告诉

这个修改是一个改进.它纠正了 EDIT 2 中提到的最严重的问题",但其他问题仍然存在.

解决方案

一种解决方案是让一个单独的进程持续运行,当收到信号时,它将使用 AppleScript 关闭 Google Sketchup 窗口.此处描述的方法使用文件进行进程间通信(drb 似乎不起作用).

首先,您必须确保 Sketchup 支持 AppleScripting.为此,请在命令提示符下执行以下命令(对不同的 Sketchup 版本进行适当的替换等):

$ defaults write/Applications/Google\ SketchUp\ 8/SketchUp.app/Contents/Info NSAppleScriptEnabled -bool YES

现在,创建一个单独的文件来关闭 Sketchup 窗口.这是我的 closer.rb 文件:

#!/usr/bin/ruby## close.rb ##def 等待(f)而 !File::exists?(f)结尾文件.delete(f)结尾定义信号(f)File.new(f, 'w').close结尾虽然是真的等待('~/temp/mutex.txt')msg = %x[osascript -e '告诉应用程序SketchUp"关闭每个窗口']信号('~/temp/conf.txt')结尾

从 shell 运行这个脚本.它一直等到文件 ~/temp/mutex.txt 被创建.创建文件后,它会运行 osascript(本质上是 AppleScript)来关闭 Sketchup 中的所有窗口,然后通过创建一个 ~/temp/conf.txt<来表示这些窗口已关闭/code> 文件.

以下是客户端代码(可以放置在您的 Sketchup 插件中),用于指示更接近的脚本:

def 等待(f)而 !File::exists?(f)结尾文件.delete(f)结尾定义信号(f)File.new(f, 'w').close结尾def close_file信号('~/temp/mutex.txt')等待('~/temp/conf.txt')结尾

close_file 向关闭脚本发出信号,然后在返回之前等待确认文件已关闭.现在您可以在 Sketchup 中关闭文件.

The Ruby API to Google SketchUp has a function, open_file, but I can't find a close_file function. Since I have to batch process many files, I want to close each file before moving on to the next, otherwise the program will crash from memory exhaustion.

What is the best way to close SketchUp files programmatically?

I am using Mac OS X and am willing to use AppleScript functions to signal the window to close.

EDIT

I am considering a few approaches that have proven fruitless so far.

  1. Using the appscript Ruby gem, as described in this question. The problem here is that I cannot get SketchUp to recognize my installed gems.
  2. In a similar vein, I am trying to use osascript (a bash program that executes AppleScripts from the shell) to close the window. That is, I call out to the shell from SketchUp's Ruby console window using one of the following:

    %x[osascript -e 'tell application "SketchUp" to close window 1']

    %x[osascript -e 'tell application "SketchUp" to close window 1' &]

    %x[osascript -e 'tell application "SketchUp" to close every window']

    %x[osascript -e 'tell application "SketchUp" to close every window' &]

    Whenever I try this second approach, SketchUp just freezes. However, when I execute any of these commands from an IRB or directly from the Bash prompt outside of SketchUp, I get the desired behavior: the model window closes (incidentally, the Ruby console window remains open, which is fine).

  3. Have a master script that launches a slave script to process each model. The slave will run within the Google SketchUp program while the master waits. When the slave is finished, it signals the master, and the master closes the SketchUp file. To do this interprocess communication, I tried using drb. However, when I try to require drb within SketchUp, I get the following message:

Error: LoadError: (eval):5:in 'require': no such file to load -- drb

EDIT 2

Having a separate process continuously running that closes Google Sketchup windows using AppleScript when signaled is clumsy for a number of reasons. First, it's ugly to have to have a separate process devoted to closing Sketchup windows. Second, the only effective way of communicating with the external script is through the creation of files, which is wasteful and the disk access may be slowing things down.

However, the most severe issue is that Sketchup is slow at responding to AppleScript commands. I have a pretty computation intensive script running in Sketchup, and it seems to starve the AppleScript response, which means that the osascript times out before the windows close. Sketchup only gets around to responding to AppleScript when there is a dialogue box prompt in Sketchup that pauses the execution of my computationally intensive script.

EDIT 3

I have modified my close_file function to pause execution of the script by displaying a dialog box. This essentially yields the current thread and allows the thread that responds to AppleScript commands to execute:

def close_file()
  f = '/temp/mutex.txt' # for finer control, use different mutex for each window you want closed
  File.new(f, 'w').close
  result = UI.messagebox "Click OK when window has closed."
end

Then the separate ruby script that closes windows via AppleScript will additionally have to click "OK" in the dialog box. AppleScript to do that is:

tell application "System Events"
    tell process "SketchUp"
        set frontmost to true
        keystroke return
    end tell
end tell

This modification is an improvement. It corrects the "most severe issue" mentioned in EDIT 2, but the other issues remain.

解决方案

One solution is to have a separate process continuously running that will close Google Sketchup windows using AppleScript when signaled. The approach described here uses files to do the interprocess communication (drb did not seem to work).

First, you have to make sure Sketchup supports AppleScripting. To do this, execute the following at the command prompt (with appropriate substitutions for different Sketchup versions, etc.):

$ defaults write /Applications/Google\ SketchUp\ 8/SketchUp.app/Contents/Info NSAppleScriptEnabled -bool YES

Now, create a separate file that will close Sketchup windows. Here is my closer.rb file:

#!/usr/bin/ruby

## closer.rb ##

def wait(f)
  while !File::exists?(f)
  end 
  File.delete(f)
end

def signal(f)
  File.new(f, 'w').close
end

while true
  wait('~/temp/mutex.txt')
  msg = %x[osascript -e 'tell application "SketchUp" to close every window'] 
  signal('~/temp/conf.txt')
end

Run this script from the shell. It waits until the file ~/temp/mutex.txt is created. Once the file is created, it runs osascript (essentially AppleScript) to close all the windows in Sketchup, and then signals that the windows were closed by creating a ~/temp/conf.txt file.

Here is the client code (which can be placed in your Sketchup plugins) that signals the closer script:

def wait(f)
  while !File::exists?(f)
  end 
  File.delete(f)
end

def signal(f)
  File.new(f, 'w').close
end

def close_file
  signal('~/temp/mutex.txt')
  wait('~/temp/conf.txt')
end

The close_file signals the closer script and then waits for a confirmation that the file was closed before returning. Now you can close files in Sketchup.

这篇关于Google SketchUp 关闭文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆