六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 31|回复: 0

wxRuby尝鲜

[复制链接]

升级  5.33%

16

主题

16

主题

16

主题

秀才

Rank: 2

积分
58
 楼主| 发表于 2013-2-7 16:07:21 | 显示全部楼层 |阅读模式
更新:终于成功弄到显示行号并自适应宽度了~
 
wxRuby最好玩的地方是它对wxWidgets多加了一层糖衣的语法。
 
安装了
 
gem install wxruby
 
之后,还要安装
 
gem install wx_sugar
 
这样子,我们不仅具有了一些:param_name => value这样的糖衣,可以使用attr_*族来暴露实例变量,还有了用do...end块来做layout和菜单的能力,比较爽的一点还有用block来处理事件。
 
简单讲解一下怎么使用:param_name => value这样的糖衣:比如wxRuby中某函数f(a,b),有了wx_sugar之后,就可以写f(:a=>5, :b=>'string')来调用。
 
下面这个小程序使用了wxAUI和wxStyledTextCtrl。用途是在非常长的文本文件中,同时搜索多个关键字,建立索引,包含上下文和定位的链接。
 
multi_searcher.rb
 
require 'rubygems'require 'wx'require 'wx_sugar/all'require 'erb'require 'ya2yaml'include Wx$KCODE = 'utf8'def min(a, b)a >= b ? b : aenddef max(a, b)a >= b ? a : bendclass KeywordsPane < Paneldef initialize(parent, options = {})super(parent, options.merge!(:size => [500, 500]))arrange_vertically doadd @keyword = TextCtrl.new(self, :style => Wx::TE_MULTILINE, :size => [-1, 200]), :proportion => 1arrange_horizontally doadd @status = StaticText.new(self, :label => '', :size => [150, -1]), :proportion => 1add Button.new(self, :label => '查找') do |button|evt_button(button) do |event|#searchget_parent.filecontent_pane.search(@keyword.get_value)endendendendendattr_reader :keyword, :statusendclass ReportPane < Panel def initialize(parent, options = {})super(parent, options.merge!(:size => [500, 500]))arrange_vertically doadd @report = HtmlWindow.new(self), :proportion => 1 do |report|evt_html_link_clicked(report) do | event |position = event.get_link_info.get_href.sub(/position\:\/\//, '').split(',')get_parent.filecontent_pane.file.set_selection position[0].to_i, position[1].to_iendendadd Button.new(self, :label => '保存报告') do |button|evt_button(button) do |event|ask4file = FileDialog.new(self, :style => FD_SAVE, :message => '保存报告', :wildcard => 'HTML files(*.html)|*.html')File.new(ask4file.get_path, 'w').write @report_text if ask4file.show_modal == Wx::ID_OKendendendendattr_reader :reportattr_writer :report_textendclass FilecontentPane < Panel def initialize(parent, options = {})super(parent, options.merge!(:size => [500, 500]))arrange_vertically doadd Button.new(self, :label => '打开要查找的文件') do |button|evt_button(button) do |event|#open fileask4file = FileDialog.new(self, :message => '打开要查找的文件')@file.load_file(ask4file.get_path) if ask4file.show_modal == Wx::ID_OK# auto adapt to the width of max line count@file.set_margin_width 0, @file.text_width(33, "__#{@file.get_line_count}") endendadd @file = StyledTextCtrl.new(self), :proportion => 1@file.set_margin_width 0, @file.text_width(33, '999') # show line numberadd StaticText.new(self, :label => '小提示:按住Ctrl+鼠标滚轮可以缩放文字大小')endenddef search(keywords)keywords_a = keywords.split(', ')@search_result = {}file_length = @file.get_text_lengthbeg_pos = 0keywords_a.each do |k|@search_result[k] = []@file.goto_pos 0@file.search_anchorwhile((beg_pos = @file.search_next(0,k)) != -1)    end_pos = beg_pos + k.lengthcontext = @file.get_text_range max(beg_pos - 520, 0), min(end_pos + 520, file_length)context.gsub! k, '<font size=7><b><u>\0</u></b></font>'# coord = [@file.line_from_position(beg_pos), @file.get_column(beg_pos)]@search_result[k] << { :context => context, :position => [beg_pos, end_pos], :coord => [@file.line_from_position(beg_pos), @file.get_column(beg_pos)]}get_parent.keywords_pane.status.set_label "正在搜索#{k}...完成%3.2f%% ..." % (beg_pos * 100.0 / file_length)@file.goto_pos end_pos + 1@file.search_anchorendendget_parent.keywords_pane.status.set_label '搜索完成,正在生成报告...'get_parent.report_pane.report.set_page report_text = ERB.new(File.read('report.html.erb'), 0, "%<>").result(binding)get_parent.keywords_pane.status.set_label ''get_parent.report_pane.report_text = report_textendattr_reader :fileendclass MyFrame < Frame   def initialize(title)super(nil, :title => title, :size => [800, 600])@mgr = AuiManager.new@mgr.set_managed_window(self)pi = AuiPaneInfo.newpi.set_name('keywords_pane').set_caption('在下面键入关键字,每个关键字之间用 一个逗号一个空格 隔开(例如keyword1, keyword2):')pi.top.set_maximize_button.set_close_button(false)@mgr.add_pane(@keywords_pane = KeywordsPane.new(self), pi)pi = AuiPaneInfo.newpi.set_name('report_pane').set_caption('查找结果报告')pi.left.set_maximize_button.set_close_button(false)@mgr.add_pane(@report_pane = ReportPane.new(self), pi)pi = AuiPaneInfo.newpi.set_name('filecontent_pane').set_caption('被查找文件')pi.center.set_maximize_button.set_close_button(false)@mgr.add_pane(@filecontent_pane = FilecontentPane.new(self), pi)@mgr.update   end      attr_reader :keywords_pane, :report_pane, :filecontent_paneendclass MyApp < App   def on_init     frame = MyFrame.new('多关键字搜索助手')     frame.show   endenda = MyApp.newa.main_loop  
程序中使用的erb模板report.html.erb:
 
<html><body><% @search_result.each do |keyword, info| %><dt><%= keyword %>(找到<%= info.length %>处)</dt><dd><% unless info.empty? %><table border=1><tr><th>位置</th><th>上下文</th></tr><% info.each do |v|%><tr><td><a href='position://<%= v[:position].join ',' %>'><%= "#{v[:coord][0]}行#{v[:coord][1]}列" %></a></td><td><pre><%= v[:context] %></pre></td></tr><% end %></table><% end %></dd><% end %></body></html>  
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表