查看完整版本: 用ruby写的一个简单日历,请大家指教

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]]

jmouse 2008-3-21 17:26

顺路,TK84.DLL哪里去搞?

xavier 2008-3-21 18:18

下一个ActiveTcl装上就行了

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

zhlong 2008-5-1 13:21

好啊,这下可以学一下了!
页: [1]
查看完整版本: 用ruby写的一个简单日历,请大家指教