dongzhi 2008-3-21 14:56
用ruby写的一个简单日历,请大家指教
刚开始学ruby,也不知道应该编点什么?呵呵。。。写了一个最简单的日历程序,只能显示指定年份和月份的日期。下一步计划从此扩展成可以对每一天添加日程。
执行结果截图:
[attach]632[/attach]
程序如下:
[code]require 'tk'
require 'tkextlib/tile'
class Calendar
def cleardays
@subframe=TkFrame.new(@baseframe)
@subframe.place('height'=>280,'width'=>490,'x'=>10,'y'=>50)
end
def monthchange(psMonth,psYear)
cleardays()
sMonth=psMonth
sYear=psYear
sMonth="0"+sMonth if sMonth.to_i < 10
puts Date.parse(sYear+'-'+sMonth+'-01').wday
puts @aMonthDays[@aMonth.index(psMonth)].to_i
DrawCurrentMonthCalendar(Date.parse(sYear+'-'+sMonth+'-01').wday, @aMonthDays[@aMonth.index(psMonth)].to_i)
end
def initialize
@dNow = Time.new
procbtnClearClick = proc {btnClear_Click}
@aYear = ("1900".."2999").to_a
@aMonth = ("1".."12").to_a
@aDayName=%w(Monday Tuesday Wednesday Thursday Friday Staurday Sunday)
if @dNow.year % 400==0 || (@dNow.year%4==0&&@dNow.year%100!=0)
@aMonthDays=%w(31 29 31 30 31 30 31 31 30 31 30 31)
else
@aMonthDays=%w(31 28 31 30 31 30 31 31 30 31 30 31)
end
@root=TkRoot.new {title "Combo box Text";height 340;width 520}
@baseframe = TkFrame.new(@root) {borderwidth 5;relief 'raised';background "white"}
@baseframe.place('height'=>340, 'width'=>520)
@subframe=TkFrame.new(@baseframe)
@subframe.place('height'=>280,'width'=>490,'x'=>10,'y'=>50)
@cmbMonth = Tk::Tile::Combobox.new(@baseframe)
@cmbMonth.values = @aMonth
@cmbMonth.place('height'=>25,'width'=>40,'x'=>10,'y'=>10)
@cmbMonth.set @dNow.month.to_s
@cmbMonth.bind("<ComboboxSelected>") {monthchange(@cmbMonth.get,@cmbYear.get)}
@cmbYear = Tk::Tile::Combobox.new(@baseframe)
@cmbYear.values = @aYear
@cmbYear.place('height'=>25,'width'=>100,'x'=>70,'y'=>10)
@cmbYear.set @dNow.year.to_s
@cmbYear.bind("<ComboboxSelected>") {monthchange(@cmbMonth.get,@cmbYear.get)}
sYear = @dNow.year.to_s
sMonth=@dNow.month.to_s
sMonth="0"+sMonth if sMonth.to_i < 10
DrawCurrentMonthCalendar(Date.parse(sYear+'-'+sMonth+'-01').wday, @aMonthDays[@aMonth.index(@dNow.month.to_s)].to_i)
end
def DrawCurrentMonthCalendar(nStartWDay, nCurrentMonthDays)
if nStartWDay != 1
@aLastMonthDay=(1..nStartWDay-1).to_a
end
@aCurrentMonthDay=(1..nCurrentMonthDays).to_a
puts @aLastMonthDay.length
nIndex=0
@aDayName.each {|i| TkLabel.new(@subframe) {text i;place('height'=>40,'width'=>70,'x'=>nIndex*70+10,'y'=>0)};nIndex+=1}
nRow=1
nColumn=0
if @aLastMonthDay.length >= 1
@aLastMonthDay.each{|i| TkLabel.new(@subframe) {text "";place('height'=>40,'width'=>70,'x'=>nColumn*70+10,'y'=>40*nRow)};nColumn=nColumn>5?0:nColumn+1;nRow=nColumn==0?nRow+1:nRow}
end
@aCurrentMonthDay.each{|i| TkLabel.new(@subframe) {text i;place('height'=>40,'width'=>70,'x'=>nColumn*70+10,'y'=>40*nRow)};nColumn=nColumn>5?0:nColumn+1;nRow=nColumn==0?nRow+1:nRow}
end
end
Calendar.new
Tk.mainloop
[/code]
[[i] 本帖最后由 dongzhi 于 2008-3-21 15:01 编辑 [/i]]
bbschat 2008-3-25 17:50
和tk比起来,我个人还是比较喜欢用 wxRuby作windows界面,wxRuby 0.6还是蛮稳定的~
不光界面好看点,关键是做出来的exe别人可以直接用。
下面这个是wxRuby 0.6自带Sample: calendar.rbw,有不少功能哦。
[code]
require 'wxruby'
include Wx
Calendar_File_About = 100
Calendar_File_Quit = 101
Calendar_Cal_Monday = 200
Calendar_Cal_Holidays = 201
Calendar_Cal_Special = 202
Calendar_Cal_Month = 203
Calendar_Cal_Year = 204
Calendar_Cal_SeqMonth = 205
Calendar_Cal_SurroundWeeks = 206
Calendar_CalCtrl = 1000
class MyPanel < Panel
def initialize(frame)
super(frame, -1)
set_auto_layout(TRUE)
begin
date = sprintf("Selected date: %s",
DateTime::today().format_iso_date())
rescue Exception=>e
date = "Selected date: (please select one)"
end
@m_date = StaticText.new(self, -1, date)
@m_calendar = CalendarCtrl.new(self, Calendar_CalCtrl,
DEFAULT_DATE_TIME,
DEFAULT_POSITION,
DEFAULT_SIZE,
CAL_MONDAY_FIRST |
CAL_SHOW_HOLIDAYS |
RAISED_BORDER)
c = LayoutConstraints.new
c.left.same_as(self, LAYOUT_LEFT, 10)
c.centre_y.same_as(self, LAYOUT_CENTRE_Y)
c.height.as_is()
c.width.as_is()
@m_date.set_constraints(c)
c = LayoutConstraints.new
c.left.same_as(@m_date, LAYOUT_RIGHT, 20)
c.centre_y.same_as(self, LAYOUT_CENTRE_Y)
c.height.as_is()
c.width.as_is()
@m_calendar.set_constraints(c)
evt_calendar(Calendar_CalCtrl) {|event| onCalendar(event)}
evt_calendar_month(Calendar_CalCtrl) {onCalMonthChange}
evt_calendar_year(Calendar_CalCtrl) {onCalYearChange}
evt_calendar_sel_changed(Calendar_CalCtrl) {|event| onCalendarChange(event)}
evt_calendar_weekday_clicked(Calendar_CalCtrl) {|event| onCalendarWeekDayClick(event)}
end
def onCalendar(event)
log_message("Selected %s from calendar",
event.get_date().format_iso_date())
end
def onCalendarChange(event)
s = sprintf("Selected date: %s", event.get_date().format_iso_date())
@m_date.set_label(s)
end
def onCalMonthChange
log_status("Calendar month changed")
end
def onCalYearChange
log_status("Calendar year changed")
end
def onCalendarWeekDayClick(event)
log_message("Clicked on %s",
DateTime::get_week_day_name(event.get_week_day()))
end
def toggle_cal_style(on,flag)
style = @m_calendar.get_window_style_flag()
if on
style |= flag
else
style &= ~flag
end
@m_calendar.set_window_style(style)
@m_calendar.refresh()
end
def highlight_special(on)
if on
attrRedCircle = CalendarDateAttr.new(CAL_BORDER_ROUND, RED)
attrGreenSquare = CalendarDateAttr.new(CAL_BORDER_SQUARE, GREEN)
attrHeaderLike = CalendarDateAttr.new(BLUE, LIGHT_GREY)
@m_calendar.set_attr(17, attrRedCircle)
@m_calendar.set_attr(29, attrGreenSquare)
@m_calendar.set_attr(13, attrHeaderLike)
else
@m_calendar.reset_attr(17)
@m_calendar.reset_attr(29)
@m_calendar.reset_attr(13)
end
@m_calendar.refresh()
end
def get_cal()
@m_calendar
end
end
class MyFrame < Frame
def initialize(title,pos,size)
super(nil, -1, title, pos, size)
# create a menu bar
menuFile = Menu.new
menuFile.append(Calendar_File_About, "&About...\tCtrl-A", "Show about dialog")
menuFile.append_separator()
menuFile.append(Calendar_File_Quit, "E&xit\tAlt-X", "Quit self program")
menuCal = Menu.new
menuCal.append(Calendar_Cal_Monday,
"Monday &first weekday\tCtrl-F",
"Toggle between Mon and Sun as the first week day",
ITEM_CHECK)
menuCal.append(Calendar_Cal_Holidays, "Show &holidays\tCtrl-H",
"Toggle highlighting the holidays",
ITEM_CHECK)
menuCal.append(Calendar_Cal_Special, "Highlight &special dates\tCtrl-S",
"Test custom highlighting",
ITEM_CHECK)
menuCal.append(Calendar_Cal_SurroundWeeks,
"Show s&urrounding weeks\tCtrl-W",
"Show the neighbouring weeks in the prev/next month",
ITEM_CHECK)
menuCal.append_separator()
menuCal.append(Calendar_Cal_SeqMonth,
"To&ggle month selector style\tCtrl-G",
"Use another style for the calendar controls",
ITEM_CHECK)
menuCal.append(Calendar_Cal_Month, "&Month can be changed\tCtrl-M",
"Allow changing the month in the calendar",
ITEM_CHECK)
menuCal.append(Calendar_Cal_Year, "&Year can be changed\tCtrl-Y",
"Allow changing the year in the calendar",
ITEM_CHECK)
# now append the freshly created menu to the menu bar...
menuBar = MenuBar.new
menuBar.append(menuFile, "&File")
menuBar.append(menuCal, "&Calendar")
menuBar.check(Calendar_Cal_Monday, TRUE)
menuBar.check(Calendar_Cal_Holidays, TRUE)
menuBar.check(Calendar_Cal_Month, TRUE)
menuBar.check(Calendar_Cal_Year, TRUE)
# ... and attach self menu bar to the frame
set_menu_bar(menuBar)
@m_panel = MyPanel.new(self)
# create a status bar just for fun (by default with 1 pane only)
create_status_bar(2)
set_status_text("Welcome to Windows!")
evt_menu(Calendar_File_Quit) {onQuit}
evt_menu(Calendar_File_About) {onAbout}
evt_menu(Calendar_Cal_Monday) {|event| onCalMonday(event)}
evt_menu(Calendar_Cal_Holidays) {|event| onCalHolidays(event)}
evt_menu(Calendar_Cal_Special) {|event| onCalSpecial(event)}
evt_menu(Calendar_Cal_Month) {|event| onCalAllowMonth(event)}
evt_menu(Calendar_Cal_Year) {|event| onCalAllowYear(event)}
evt_menu(Calendar_Cal_SeqMonth) {|event| onCalSeqMonth(event)}
evt_menu(Calendar_Cal_SurroundWeeks) {|event| onCalShowSurroundingWeeks(event)}
evt_update_ui(Calendar_Cal_Year) {|event| onAllowYearUpdate(event)}
end
def onQuit
# TRUE is to force the frame to close
close(TRUE)
end
def onAbout
message_box("CalendarCtrl sample\nゥ 2000 Vadim Zeitlin",
"About Calendar", OK | ICON_INFORMATION, self)
end
def onCalMonday(event)
enable = get_menu_bar().is_checked(event.get_id())
@m_panel.toggle_cal_style(enable, CAL_MONDAY_FIRST)
end
def onCalHolidays(event)
enable = get_menu_bar().is_checked(event.get_id())
@m_panel.get_cal().enable_holiday_display(enable)
end
def onCalSpecial(event)
@m_panel.highlight_special(get_menu_bar().is_checked(event.get_id()))
end
def onCalAllowMonth(event)
allow = get_menu_bar().is_checked(event.get_id())
@m_panel.get_cal().enable_month_change(allow)
end
def onCalAllowYear(event)
allow = get_menu_bar().is_checked(event.get_id())
@m_panel.get_cal().enable_year_change(allow)
end
def onCalSeqMonth(event)
allow = get_menu_bar().is_checked(event.get_id())
@m_panel.toggle_cal_style(allow, CAL_SEQUENTIAL_MONTH_SELECTION)
end
def onCalShowSurroundingWeeks(event)
allow = get_menu_bar().is_checked(event.get_id())
@m_panel.toggle_cal_style(allow, CAL_SHOW_SURROUNDING_WEEKS)
end
def onAllowYearUpdate(event)
event.enable( get_menu_bar().is_checked(Calendar_Cal_Month))
end
end
class RbApp < App
def on_init()
frame = MyFrame.new("Calendar Windows sample", Point.new(50, 50), Size.new(450, 340))
frame.show(TRUE)
end
end
a = RbApp.new
a.main_loop()
[/code]
[[i] 本帖最后由 bbschat 于 2008-3-25 18:29 编辑 [/i]]
dongzhi 2008-3-27 09:19
bbschat:
谢谢你的回复!wxRuby的这个例子就是我最终想要实现的样子。这下有的抄了!呵呵。。。
drive2me 2008-3-27 13:22
哈哈,那也要抄个明白呀。
弄出来了,给我一份。最好可以弄得和Activedesk的日历软件一样。
那就更好了。
googya 2008-5-1 00:55
tk48怎麽不见了
tk48。dll好像没有啊,应该是什么问题
require 'tk'
require 'tkextlib/tile'
class Calendar
def cleardays
@subframe=TkFrame.new(@baseframe)
@subframe.place('height'=>280,'width'=>490,'x'=>10,'y'=>50)
end
def monthchange(psMonth,psYear)
cleardays()
sMonth=psMonth
sYear=psYear
sMonth="0"+sMonth if sMonth.to_i < 10
puts Date.parse(sYear+'-'+sMonth+'-01').wday
puts @aMonthDays[@aMonth.index(psMonth)].to_i
DrawCurrentMonthCalendar(Date.parse(sYear+'-'+sMonth+'-01').wday, @aMonthDays[@aMonth.index(psMonth)].to_i)
end
def initialize
@dNow = Time.new
procbtnClearClick = proc {btnClear_Click}
@aYear = ("1900".."2999").to_a
@aMonth = ("1".."12").to_a
@aDayName=%w(Monday Tuesday Wednesday Thursday Friday Staurday Sunday)
if @dNow.year % 400==0 || (@dNow.year%4==0&&@dNow.year%100!=0)
@aMonthDays=%w(31 29 31 30 31 30 31 31 30 31 30 31)
else
@aMonthDays=%w(31 28 31 30 31 30 31 31 30 31 30 31)
end
@root=TkRoot.new {title "Combo box Text";height 340;width 520}
@baseframe = TkFrame.new(@root) {borderwidth 5;relief 'raised';background "white"}
@baseframe.place('height'=>340, 'width'=>520)
@subframe=TkFrame.new(@baseframe)
@subframe.place('height'=>280,'width'=>490,'x'=>10,'y'=>50)
@cmbMonth = Tk::Tile::Combobox.new(@baseframe)
@cmbMonth.values = @aMonth
@cmbMonth.place('height'=>25,'width'=>40,'x'=>10,'y'=>10)
@cmbMonth.set @dNow.month.to_s
@cmbMonth.bind("<ComboboxSelected>") {monthchange(@cmbMonth.get,@cmbYear.get)}
@cmbYear = Tk::Tile::Combobox.new(@baseframe)
@cmbYear.values = @aYear
@cmbYear.place('height'=>25,'width'=>100,'x'=>70,'y'=>10)
@cmbYear.set @dNow.year.to_s
@cmbYear.bind("<ComboboxSelected>") {monthchange(@cmbMonth.get,@cmbYear.get)}
sYear = @dNow.year.to_s
sMonth=@dNow.month.to_s
sMonth="0"+sMonth if sMonth.to_i < 10
DrawCurrentMonthCalendar(Date.parse(sYear+'-'+sMonth+'-01').wday, @aMonthDays[@aMonth.index(@dNow.month.to_s)].to_i)
end
def DrawCurrentMonthCalendar(nStartWDay, nCurrentMonthDays)
if nStartWDay != 1
@aLastMonthDay=(1..nStartWDay-1).to_a
end
@aCurrentMonthDay=(1..nCurrentMonthDays).to_a
puts @aLastMonthDay.length
nIndex=0
@aDayName.each {|i| TkLabel.new(@subframe) {text i;place('height'=>40,'width'=>70,'x'=>nIndex*70+10,'y'=>0)};nIndex+=1}
nRow=1
nColumn=0
if @aLastMonthDay.length >= 1
@aLastMonthDay.each{|i| TkLabel.new(@subframe) {text "";place('height'=>40,'width'=>70,'x'=>nColumn*70+10,'y'=>40*nRow)};nColumn=nColumn>5?0:nColumn+1;nRow=nColumn==0?nRow+1:nRow}
end
@aCurrentMonthDay.each{|i| TkLabel.new(@subframe) {text i;place('height'=>40,'width'=>70,'x'=>nColumn*70+10,'y'=>40*nRow)};nColumn=nColumn>5?0:nColumn+1;nRow=nColumn==0?nRow+1:nRow}
end
end
Calendar.new
Tk.mainloop