Mac OS X下让ruby支持tcl/tk

我记得在老早在OS X10.8下使用ruby1.9.x的时候只要到下载安装ActiveTcl8.5,没怎么配置就运行tk好好的。但是近日想重新执行下tk代码,发现在require ‘tk‘的时候就报错鸟!现在用的是ruby2.1.3版本。上网搜了一下,1.9.x之后的版本默认不再将tcl/tk支持编译到ruby里面,so如果你想用则必须重新编译ruby!我勒个去!就不能做成个gem吗?但在多种外围尝试无果的的情况下只有一条路,就是重新编译ruby了...

到ruby官网下载最新的ruby2.1.5的源代码15MB左右,解压后257MB,console进入解压目录,输入:

./configure -prefix=/Users/apple/src/ruby_src/ruby2.1.5_installed --with-arch=x86_64,i386 --enable-pthread --enable-shared --with-tk --with-tcl

注意-prefix必须要绝对路径,否则不让过;这是你要最后安装ruby2.1.5的路径,一旦固定下来,就不可以再动了。因为我后来用rvm也安装了ruby2.1.5版,所以这里换了个临时位置,只是测试用的。接着可以输入make命令编译ruby,大概要等一会,最后执行make install就将ruby2.1.5安装到了我前面设定的位置上。下面测试一下对tk的支持如何:

[email protected]: bin$ls

erb    gem   
irb    rake  
rdoc   ri    
ruby   testrb

[email protected]: bin$./ruby -e "require ‘tk‘"

可以看到是ok的,然后运行一下我的tk.rb看一下效果(代码节选):

require 'dbm'
#require 'tempfile'
#require 'zip/zip'
#require 'win32api'

#PATH = '/Users/apple/src/c_src/ruby-1.9.3-p362/ext/tk/lib/'

require 'tk'
#require PATH+'tk'
require 'tkextlib/tkimg/bmp'
require 'tkextlib/tkimg/jpeg'
require 'tkextlib/tkimg/png'
require 'tkextlib/iwidgets'
require 'tkextlib/bwidget'

SM_CXSCREEN = 0
SM_CYSCREEN = 1
def get_screen_size
	#get_screen_size_nv = Win32API.new('user32','GetSystemMetrics',['L'],'L')
	#x = get_screen_size_nv.Call(SM_CXSCREEN)
	#y = get_screen_size_nv.Call(SM_CYSCREEN)
	`./s`.split.map {|x| x.to_i}
	#[x,y]
end

def zip(path)
	zip_path = path + '.zip'
	File.delete(zip_path) if File.exist? zip_path
	Zip::ZipFile.open(zip_path,Zip::ZipFile::CREATE) {|f| f.add(File.split(path)[1],path)}
end

def unzip(path)
	unzip_path = path[0..-5]
	Zip::ZipFile.open(path) {|f| f.extract(f.entries[0],unzip_path) {true}}
end

DB_PATH = File.expand_path(".") + '/movies.dbm'

#zip(DB_PATH + '.dir')
#zip(DB_PATH + '.pag')

#unzip(DB_PATH + '.dir.zip')
#unzip(DB_PATH + '.pag.zip')

db = DBM.new(DB_PATH)
#db.clear

at_exit {
	db.close
	#压缩数据库
	#zip(DB_PATH + '.dir')
	#zip(DB_PATH + '.pag')
	#File.delete(DB_PATH + '.dir');File.delete(DB_PATH + '.pag')
}

ROOT_W = 1000
ROOT_H = 610

x,y = get_screen_size
#计算屏幕居中显示时需要移动到的坐标
mov_x = (x - ROOT_W)/2
mov_y = (y - ROOT_H)/2

root = TkRoot.new(:title=>"movie query v1.2")
Tk::Wm.geometry(root,"+#{mov_x}+#{mov_y}")
#Tk::Wm.attributes(root,:toolwindow=>true)
Tk::Wm.geometry(root,"#{ROOT_W}x#{ROOT_H}")
Tk::Wm.minsize(root,ROOT_W,ROOT_H)
Tk::Wm.maxsize(root,ROOT_W,ROOT_H)

img_love = TkPhotoImage.new(:file=>File.expand_path(".") + '/logo.gif')
Tk::Wm.iconphoto(root,img_love)

def dlgbox_input_name(in_name)
	#puts Tk::Wm.state dlg
	#Tk::Wm.deiconify dlg

	dlg = Tk::Toplevel.new(:title=>"输入演员名")
	#Tk::Wm.attributes(dlg,:toolwindow=>true)
	Tk::Wm.attributes(dlg,:notify=>true)
	#隐藏窗口
	#Tk::Wm.withdraw dlg

	out_name = nil

	txt_input_name = Tk::Tile::Entry.new(dlg,:width=>40) do
		grid :row=>0,:column=>0
	end
	txt_input_name.value = in_name

	btn_add_name = Tk::Tile::Button.new(dlg) do
		text "添 加"
		command do
			out_name = txt_input_name.value
			dlg.destroy
		end
		grid :row=>1,:column=>0
	end

	txt_input_name.bind("Return") do
		btn_add_name.invoke
	end

	txt_input_name.focus

	#将toplevel窗口(对话框窗口)设为主窗口的"瞬时窗口"
	Tk::Wm.transient dlg
	#模式对话框
	Tk::BWidget.grab :set,dlg
	#暂时挂起主窗口线程
	#TkTimer.new.tkwait dlg
	dlg.wait_window
	out_name
end

#(r0,c0)
lab_app = Tk::Tile::Label.new do
	text "大熊猫最爱电影查询工具"
	font "新宋体 14 bold"
	foreground "blue"
	grid :row=>0,:column=>0,:columnspan=>8,:padx=>10,:pady=>10
end

#(r1,c0)
lab_names = Tk::Tile::Label.new do
	text "电影名称"
	font "新宋体 12 bold"
	grid :row=>1,:column=>0,:padx=>10,:pady=>10
end

#(r1,c1)
txt_names = TkText.new(:width=>35,:height=>2) do
	font "新宋体 12 bold"
	grid :row=>1,:column=>1
end

#(r2,c0)
lab_stars = Tk::Tile::Label.new do
	text "熊猫星级"
	font "新宋体 12 bold"
	grid :row=>2,:column=>0,:padx=>10,:pady=>40,:sticky=>:n
end

img_file = File.open(File.expand_path(".") + '/star.jpg','r+b')
img_data = img_file.read
#img_star = TkPhotoImage.new(:data=>img_data,:gamma=>0.01)
img_star = TkPhotoImage.new(:data=>img_data,:palette=>10)
img_star_chk = TkPhotoImage.new(:data=>img_data)
img_file.close

star = 0
btn_stars = []
btn_chks = [false,false,false,false,false]

clr_all_chk = proc do
	btn_chks = [false]*5
	btn_stars.each do |btn|
		btn.configure(:image=>img_star)
	end
end

#(r2,c1)
frm_stars = TkFrame.new do
	grid :row=>2,:column=>1,:padx=>10,:pady=>10,:sticky=>:n
	5.times do |i|
		btn_stars << TkButton.new(self,:width=>45,:height=>50) do
			text i.to_s
			image img_star
			relief :flat
			grid :row=>0,:column=>i+1
			command do
				idx = self.cget(:text).to_i
				unless btn_chks[idx]
					btn_chks[0..idx] = [true]*(idx+1)
				else
					if btn_chks[idx+1]
						btn_chks[(idx+1)..-1] = [false]*(5-idx-1)
					else
						btn_chks[0..idx] = [false]*(idx+1)
					end
				end

				5.times do |j|
					img = if btn_chks[j];img_star_chk else img_star end
					btn_stars[j].configure(:image=>img)
				end
				star = btn_chks.count(true)
			end
		end
	end
end

#(r3,c0)
lab_direct = Tk::Tile::Label.new do
	text "导 演"
	font "新宋体 12 bold"
	grid :row=>3,:column=>0
end

#(r3,c1)
txt_direct = Tk::Tile::Entry.new(:width=>35) do
	font "新宋体 12 bold"
	grid :row=>3,:column=>1
end

#(r4,c0)
lab_nil = Tk::Tile::Label.new do
	grid :row=>4,:column=>0
end

#(r5,c0)
lab_artist = Tk::Tile::Label.new do
	text "演 员"
	font "新宋体 12 bold"
	grid :row=>5,:column=>0,:padx=>10,:pady=>10,:sticky=>:n
end

lst_artist = lst_xroll = lst_yroll = nil
#(r5,c2)
lst_yroll = Tk::Tile::Scrollbar.new do
	command proc{|*idx|lst_artist.yview *idx}
	grid(:row=>5,:column=>2,:sticky=>:ns)
end

#(r11,c4)
btn_del = Tk::Tile::Button.new(frm_btns) do
	text "删 除
	command do
		if db.each_key.select {|k|a = k.split(" ")[0].force_encoding("gbk");
		b = txt_names.value.split(" ")[0]
		a =~ /#{b}/}.count == 0
			Tk.messageBox(:icon=>:error,:type=>:ok,:title=>"error",			:message=>"该主电影名不在数据库中!");break
		end
		db.delete(txt_names.value)
		txt_names.value = ""
	end
	grid :row=>11,:column=>4,:padx=>10,:sticky=>:n
end

btn_exit = Tk::Tile::Button.new(frm_btns) do
	text "退 出"
	command do
		exit
	end
	grid :row=>11,:column=>5,:padx=>10,:sticky=>:n
end

#TkGrid.grid(btn_add,"-","x",btn_del,:sticky=>:nsew)

#(r0,c5)
cvs_line = TkCanvas.new(:width=>"0.1c") do
	create :line,"0.1c","1c","0.1c","30c",:dash=>"10",:width=>4,:fill=>"blue"
	grid :row=>0,:column=>5,:rowspan=>12,:sticky=>:wns
end

yrl_lst_find = nil
#(r1,c6)
lst_find = TkListbox.new(:width=>20,:height=>20) do
	font "新宋体 12 bold"
	yscrollcommand proc {|*idx|yrl_lst_find.set *idx}
	grid :row=>1,:column=>6,:rowspan=>13,:sticky=>:wn
end

#(r1,c7)
yrl_lst_find = Tk::Tile::Scrollbar.new do
	command proc{|*idx|lst_find.yview *idx}
	grid(:row=>1,:column=>7,:rowspan=>5,:sticky=>:wns)
end

flash_movie_info = proc do |name|
	vals = eval(db[name].force_encoding("gbk"))
	#先按一下btn[0],以防上一个star>0
	#btn_stars[0].invoke
	idx = vals[:star].to_i

	#idx -= 1 if idx > 0
	clr_all_chk[]
	btn_stars[idx-1].invoke if idx > 0

	txt_names.value = name

	txt_direct.value = vals[:direct]
	list.value = vals[:artist]

	scl_clarity.value = vals[:scl].to_i

	txt_size.value = vals[:size]
	txt_len.value = vals[:len]
	txt_locate.value = vals[:locate]
	txt_mark.value = vals[:mark]
	txt_note.value = vals[:note]

	pic = TkPhotoImage.new(:data=>vals[:pic].force_encoding("ASCII-8BIT")) if vals[:pic]

	lab_pic.configure(:image=>pic)
end

flash_vals = proc do |vals|
	idx = vals[:star].to_i
	clr_all_chk[]
	btn_stars[idx-1].invoke if idx > 0

	txt_names.value = vals[:name]

	txt_direct.value = vals[:direct]
	list.value = vals[:artist]

	scl_clarity.value = vals[:scl].to_i

	txt_size.value = vals[:size]
	txt_len.value = vals[:len]
	txt_locate.value = vals[:locate]
	txt_mark.value = vals[:mark]
	txt_note.value = vals[:note]

	pic = TkPhotoImage.new(:data=>vals[:pic].force_encoding("ASCII-8BIT")) if vals[:pic]
	lab_pic.configure(:image=>pic)
end

lst_find.bind("<ListboxSelect>") do
	i = lst_find.curselection[0]
	if i.to_s != ""
		name = lst_find.get(i)
		flash_movie_info[name]
	end
end

lst_find.bind("ButtonRelease-1") do
	i = lst_find.curselection[0]
	if i.to_s != ""
		name = lst_find.get(i)
		flash_movie_info[name]
	end
end

#(r10,c6)
txt_find = Tk::Tile::Entry.new(:width=>20) do
	font "新宋体 12 bold"
	grid :row=>10,:column=>6
end

btn_find = nil
txt_find.bind("Return") do
	btn_find.invoke
end

#(r11,c6)
btn_find = Tk::Tile::Button.new do
	text "查 找"
	command do
		name_to_find = txt_find.value
		next if name_to_find == ""

		lst_find.clear
		if name_to_find == "*"
			db.each_key.select do |k|
				lst_find.insert(:end,k.force_encoding("gbk"))
			end
			next
		end

		db.each_key.select do |k|
			names = k.force_encoding("gbk").split(" ")
			for n in names
				(lst_find.insert(:end,k.force_encoding("gbk"));break) if n =~ /#{name_to_find}/
			end
		end
	end
	grid :row=>11,:column=>6
end

menu = TkMenu.new(:parent=>root,:tearoff=>0)
root.configure(:menu=>menu)

menu_file = TkMenu.new(:parent=>root,:tearoff=>0)

cmd_import = proc do
	imp_path = Tk.getOpenFile
	next if imp_path == ""

	data = nil
	File.open(imp_path,"r+") do |f|
		data = f.read
	end
	vals = eval(data.force_encoding("gbk"))
	flash_vals[vals]
end

menu_file_import = menu_file.add_command(:label=>"Import movie",:underline=>1,:command=>cmd_import)

cmd_export = proc do
	unless chk_vals[]
		Tk.messageBox(:icon=>:error,:type=>:ok,:title=>"error",			:message=>"请选择一部电影!");next
	end

	exp_path = Tk.getSaveFile
	next if exp_path == ""

	m = get_vals[]
	m[:name] = txt_names.value
	File.open(exp_path,"w+") do |f|
		f.write m.to_s
	end
end

menu_file_export = menu_file.add_command(:label=>"Export movie",:underline=>1,:command=>cmd_export)
menu_file.add_separator

cmd_exit = proc do
	exit
end
menu_file_exit = menu_file.add_command(:label=>"Exit",:underline=>2,:command=>cmd_exit)

menu.add_cascade(:menu=>menu_file,:label=>"File",:underline=>1)
#menu_file = menu.add(:cascade,:label=>"File",:underline=>0)

Tk.mainloop

界面丑是丑了点,不过后期可以再调整哦,关键是这段代码windows,linux,OS X下跑都没问题啊,轻松跨平台鸟:

还有一种办法是用rvm重新安装支持tcl/tk的版本:

rvm reinstall 2.1.5 --enable-shared --enable-pthread --with-tk --with-tcl

不过我试了一下,在brew update无限卡住了,所以才有了开篇的那一坨文章...

最后本猫觉得这样用不太爽,尤其是自己编译的irb用不了,因为其还是调用了rvm的路径。要替换也很容易,做软连接吧:

[email protected]: rubies$ls -lh

total 16

lrwxr-xr-x  1 apple  staff    35B 12 10 13:03 default -> /Users/apple/.rvm/rubies/ruby-2.1.5

drwxr-xr-x  8 apple  staff   272B  7 27 19:47 ruby-2.1.2

lrwxr-xr-x  1 apple  staff    45B 12 10 16:08 ruby-2.1.5 -> /Users/apple/src/ruby_Src/ruby2.1.5_installed

drwxr-xr-x  8 apple  staff   272B 12 10 13:02 tmp_ruby-2.1.5

先把原来的ruby目录改名,然后将编译的路径加入即可,可以看到其版本号显示略有不同:

[email protected]: rubies$ruby -v

ruby 2.1.5p273 (2014-11-13 revision 48405) [universal.x86_64-darwin14.0]

[email protected]: rubies$./tmp_ruby-2.1.5/bin/ruby -v

ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin14.0]

时间: 2024-10-10 08:20:21

Mac OS X下让ruby支持tcl/tk的相关文章

Qt在Mac OS X下的编程环境搭建(配置Qt库和编译器,有图,很清楚)

尊重作者,支持原创,如需转载,请附上原地址:http://blog.csdn.net/libaineu2004/article/details/46234079 在Mac OS X下使用Qt开发,需要配置Qt库和编译器.编译器只能使用苹果公司自主研发的Clang.1.分别下载并安装XCode和Command Line Tools(必须安装),安装完毕后,Clang就有了. https://developer.apple.com/downloads/ 2.下载Qt并默认安装 http://down

解决 Mac OS X 下 IntelliJ IDEA、jEdit 等 Java 程序中文标点输入无效的方法

Mac OS X 下基于 Java 的程序(如 IntelliJ IDEA.jEdit 等)会出现中文标点输入无效的问题,在中文输入法状态,可以输入中文字,但输入中文标点最后上去的是英文标点.查阅了相关资料,原来这是 Java 自己的 bug.从 Java 8u51 版本开始就出现了这个 bug,一直到现在最新的 Java 8u72 仍然如此,但是老版本 Java 8u45 是没有这个问题的.所以,可以采取变通的方法,在 Mac OS X 上同时装一个老版本的 JDK 8u45,不会影响已经安装

Qt在Mac OS X下的编程环境搭建

尊重作者,支持原创,如需转载,请附上原地址:http://blog.csdn.net/libaineu2004/article/details/46234079 在Mac OS X下使用Qt开发,需要配置Qt库和编译器.编译器只能使用苹果公司自主研发的Clang.1.分别下载并安装XCode和Command Line Tools(必须安装),安装完毕后,Clang就有了. https://developer.apple.com/downloads/ 2.下载Qt并默认安装 http://down

转:Mac OS X下Sublime Text (V2.0.1)破解

Mac OS X下Sublime Text (V2.0.1)破解 Mac OS X下Sublime Text (V2.0.1)破解 (2013-03-07 14:02:54) 转载▼     正版的买个license其实并不贵,定价为70美元.如果不买license,也可access所有功能,只是偶有pop-up提示购买.有能力的请支持正版! 以下是step-by-step instructions: 1. 在http://www.sublimetext.com/上根据操作系统选择对应版本下载,

Mac OS X 下捕获App局域网通讯包

Mac OS X 下捕获App局域网通讯包 一.抓包模式 因为工作关系,经常要分析App wifi通讯协议.我的开发电脑是Mac Book. 大体有如下几种模式: + App与服务器进行http通讯,这种情况下Http调试神器Charles 就派上用场.(这个参见本人其它博文) + App 与智能设备进行Wifi设备,一般是TCP包居多,往往不需要联入互联网,只是局域通讯.它需要用抓包软件Wireshark. 本文就是这种局域网Tcp模式,这种模式下无法使用Charles代理器模式,直接在电脑上

Mac OS X下的USB设备连接与访问

由于COM协议的广泛使用,很多设备虽然接口改为了USB,但内部数据通讯协议仍然使用的是COM(即传统的RS232串口协议,新的使用TTL).很多设备使用了PL2302/CH340/FTDI等芯片来通过USB模拟出串口协议,如Arduino/NodeMCU等都采用类似的机制. 在Windows下,安装驱动程序后可以直接在"设备管理器"找到模拟的COM设备(找不到的话,可能驱动有问题了,有时候重新启动或重新安装能解决).在Linux下可以通过lsusb和dmesg列出USB端口和所模拟的C

Mac OS X 下安装python的MySQLdb模块

参考资料: mac os x下python安装MySQLdb模块   http://www.codeif.com/post/1073/ MAC OSX使用Python安装模块有关问题  http://www.myexception.cn/operating-system/1616547.html 在Mac OS X 中安装好了MySQL和Django,在Django中访问MySQL数据库时,提示“ImportError: No module named MySQLdb”,是由于没有安装Pytho

在Mac OS X下安装Android Studio

在Mac OS X下安装Android Studio只需要几步. 1. 下载Android Studio安装包(.dmg). 2. 打开Terminal输入java -version命令查看是否已安装JDK(1.8版本及以上),如果未安装就去http://www.oracle.com/technetwork/java/javase/downloads/index.html下载安装. 3. 双击Android Studio的dmg安装文件,把Android Studio拖放到Application

在mac os x 下升级emacs

大概是09年的时候接触到emacs这个编辑器,当时我们c语言老师用的,他自信满满,而那时我是个vimer,所以每次看他按那么多组合键我就替他感觉手指头累啊. 再后来我用了几年vim写代码,再后来用了许多脚本语言,还有遇到一些问题vim无法解决的. 后来我在12年的时候开始尝试着用emacs. 刚开始确实很不好用,但是后来越来越喜欢emacs. 当然vim我还是在用.现在重新拾起他们两个.我的最爱.哈哈哈哈. 回到正题,emacs在mac os x 下版本太低了.<blockquote>liwe