예제 #1
0
class CharacterWeaponFrame(MainFrameWithTable):
    def __init__(self, master, **kwargs):
        MainFrameWithTable.__init__(self, master, **kwargs)
        # 滑鼠中鍵事件註冊,設定為更改角色詳細資訊,並選取該列
        self.table_view.bind(
            "<Button-2>",
            lambda event: self.opening_character_update_window(event))
        self.set_table_place(6, 31)
        self.filter_manager = FilterRuleManager()
        self.table_model = TableModelAdvance()
        self.table_model.set_columns(CharacterWeapon.TABLE_VIEW_COLUMNS)
        self.table_view.setModel(self.table_model)

        self.characters = CharacterWeaponModel.select_character_weapon_list()
        self._init_upper_frame()
        self.update_table()

    def _init_upper_frame(self):
        self.insufficiently = ToggleButton(self,
                                           text='Insufficiently',
                                           width=14,
                                           font=(SCP, 8),
                                           relief=RIDGE)
        self.insufficiently.bind(
            '<Button-1>',
            lambda event: (self.filter_manager.set_specific_condition(
                'unforged',
                0 if self.insufficiently.is_selected else CONDITIONLESS,
                rule=not_match_request), self.update_table()),
            add='+')
        self.insufficiently.place(x=380, y=3)

        Label(self, text='Type:', width=5, font=(MS_JH, 11)).place(x=510, y=3)
        self.type_selector = FilteredCombobox(self,
                                              width=4,
                                              font=(MS_JH, 9),
                                              justify=CENTER,
                                              state='readonly')
        self.type_selector['values'] = WEAPONS
        self.type_selector.place(x=558, y=5)
        self.type_selector.bind(
            '<<ComboboxSelected>>', lambda event:
            (self.filter_manager.set_specific_condition(
                'weapon_type', self.type_selector.get()), self.update_table()))

        button = Button(self, text='新增', width=8, font=(MS_JH, 10))
        button.place(x=640, y=1)
        button["command"] = lambda: open_adding_new_character_weapon_window(
            self,
            callback=lambda cw:
            (self.characters.append(cw), self.update_table()))

    def update_table(self):
        results = self.filter_manager.filter(self.characters)
        self.table_model.set_rows(
            [result.get_table_view_info() for result in results])
        self.table_model.setSortOrder(columnName='Left', reverse=1)
        self.redisplay_table()

    # 更改角色資訊
    def opening_character_update_window(self, event):
        self.table_view.handle_left_click(event)
        character = self.get_corresponding_character_weapon_in_row(
            self.table_view.get_row_clicked(event)).character
        open_updating_character_window(self, character, lambda: None)

    # 編輯武器狀態
    def do_double_clicking(self, event):
        character_weapon = self.get_corresponding_character_weapon_in_row(
            self.table_view.get_row_clicked(event))
        open_updating_character_weapon_window(self, character_weapon,
                                              self.update_table)

    def do_dragging_along_right(self, row_number):
        character = self.get_corresponding_character_weapon_in_row(row_number)
        delete_character_weapon_with_conforming(
            self, character, lambda: (self.characters.remove(
                character), self.update_table()))  # 直接從 list 中拿掉,不用重撈

    def get_corresponding_character_weapon_in_row(self, row_number):
        selected_name = self.table_model.getCellRecord(row_number, 0)
        for character in self.characters:
            if character.nickname.encode('utf-8') == selected_name:
                return character
예제 #2
0
class SpecificStageDroppedCanvas(Canvas):
    KEY_TITLE = 'title'
    KEY_TOTAL = 'total'
    KEY_DROPS = "drops"
    KEY_VALUES = "values"
    KEY_DEFAULTS = "defaults"

    def __init__(self, master, section, **kwargs):
        Canvas.__init__(self, master, **kwargs)
        self.title = StringVar()
        self.section = section
        self._init_frame()
        self._init_fields()

    def _init_frame(self):
        Label(self, textvariable=self.title, width=13, font=(MS_JH, 14)).place(x=12, y=5)
        self.box_1_button = ToggleButton(self, text='1st', width=3, font=(SCP, 11), relief=RIDGE)
        self.box_1_button.place(x=5 + 43 * 0, y=39)
        self.box_2_button = ToggleButton(self, text='2nd', width=3, font=(SCP, 11), relief=RIDGE)
        self.box_2_button.place(x=5 + 43 * 1, y=39)
        self.box_3_button = ToggleButton(self, text='3rd', width=3, font=(SCP, 11), relief=RIDGE)
        self.box_3_button.place(x=5 + 43 * 2, y=39)
        self.box_4_button = ToggleButton(self, text='4th', width=3, font=(SCP, 11), relief=RIDGE)
        self.box_4_button.place(x=5 + 43 * 3, y=39)

        submit_button = Button(self, text='Submit', width=17, font=(SCP, 11), relief=RIDGE)
        submit_button.place(x=5, y=76)
        submit_button.bind('<Button-1>', lambda event: self.submitting())

        current_y = 114
        self.total_desc = StringVar()
        Label(self, textvariable=self.total_desc, width=16, font=(SCP, 11)).place(x=13, y=current_y)
        current_y += 28
        self.drop_vars = [IntVar(), IntVar(), IntVar(), IntVar()]
        for i in range(4):
            Label(self, textvariable=self.drop_vars[i], width=3, font=(SCP, 11), relief=GROOVE). \
                place(x=6 + 43 * i, y=current_y)
        current_y += 29
        self.values_desc = StringVar()
        Label(self, textvariable=self.values_desc, width=16, font=(SCP, 11)).place(x=13, y=current_y)

    def _init_fields(self):
        data_record = get_data_record(self.section)
        self.title.set(data_record[self.KEY_TITLE])
        self.statistic_tacker = DroppedStatisticTacker(4)
        self.statistic_tacker.set(data_record[self.KEY_TOTAL], data_record[self.KEY_DROPS])
        self.values = data_record[self.KEY_VALUES]

        self._init_buttons_state(data_record[self.KEY_DEFAULTS])
        self._update_statistics()

    def _update_statistics(self):
        from itertools import izip

        self.total_desc.set('Times : %2d ' % self.statistic_tacker.times)
        for i in range(4):
            self.drop_vars[i].set(self.statistic_tacker.drops[i])
        self.values_desc.set('Value : %1.2f' % (sum(p * q for p, q in izip(
            self.values, self.statistic_tacker.get_statistics_ratio())) / 100))

    def _init_buttons_state(self, defaults):
        self.box_1_button.set_is_selected(defaults[0])
        self.box_2_button.set_is_selected(defaults[1])
        self.box_3_button.set_is_selected(defaults[2])
        self.box_4_button.set_is_selected(defaults[3])

    def submitting(self):
        self.statistic_tacker.record([self.box_1_button.is_selected, self.box_2_button.is_selected,
                                      self.box_3_button.is_selected, self.box_4_button.is_selected])

        data_record = get_data_record(self.section)
        data_record[self.KEY_TOTAL] = self.statistic_tacker.times
        data_record[self.KEY_DROPS] = self.statistic_tacker.drops
        save_data_record()

        self._init_buttons_state(data_record[self.KEY_DEFAULTS])
        self._update_statistics()
class CharacterPowerWindow(BasicWindow):
    def __init__(self, master, character_power, callback, width=558, height=222, **kwargs):
        BasicWindow.__init__(self, master, width=width, height=height, **kwargs)
        self.title("CharacterPower")
        self.character_power = character_power
        self.callback = callback
        self._init_widget()
        self._init_content()
        # 事件註冊,設定為更改角色詳細資訊
        self.bind("-", lambda event: self.open_updating_character_window())

    def _init_widget(self):
        current_y_diff = 28

        current_y = 20
        current_x = 23
        self.character_selector = CharacterSelectorCanvas(self, self.character_power.character)
        self.character_selector.place(x=current_x, y=current_y - 3)
        callback_after_selection = lambda event: (self.filling_in_entries_by_character(), level_entry.focus_set())
        self.character_selector.bind("<Return>", callback_after_selection)
        self.character_selector.bind("-", callback_after_selection)

        current_x += 145
        Label(self, width=5, text="Level", font=(SCP, 12)).place(x=current_x, y=current_y)
        self.level = StringVar()
        level_entry = Entry(self, width=5, textvariable=self.level, font=(SCP, 12), justify=CENTER)
        level_entry.place(x=current_x + 2, y=current_y + current_y_diff)
        level_entry.bind("<Return>", lambda x: (self.filling_in_atk_by_level(), atk_entry.focus_set()))

        current_x += 62
        Label(self, width=5, text="Atk", font=(SCP, 12)).place(x=current_x, y=current_y)
        self.atk = StringVar()
        atk_entry = Entry(self, width=5, textvariable=self.atk, font=(SCP, 12), justify=CENTER)
        atk_entry.place(x=current_x + 3, y=current_y + current_y_diff)
        atk_entry.bind("<Return>", lambda x: active_factor_entry.focus_set())

        current_x += 70
        Label(self, width=25, text="Addition", font=(SCP, 12)).place(x=current_x, y=current_y)
        self.addition = StringVar()
        addition_entry = Entry(self, width=25, textvariable=self.addition, font=(MS_JH, 12), justify=CENTER)
        addition_entry.place(x=current_x + 3, y=current_y + current_y_diff)
        addition_entry.bind("<Return>", lambda x: self.presently.focus_set())

        current_y += 14 + current_y_diff * 2
        current_x = 27
        Label(self, width=8, text="AtkRaised", font=(SCP, 10)).place(x=current_x + 1, y=current_y + 3)
        self.atk_raised = StringVar()
        atk_raised_entry = Entry(self, width=7, textvariable=self.atk_raised, font=(SCP, 12), justify=CENTER)
        atk_raised_entry.place(x=current_x, y=current_y + current_y_diff)
        atk_raised_entry.bind("<Return>", lambda x: active_factor_entry.focus_set())

        current_x += 90
        Label(self, width=7, text="HitRate", font=(SCP, 11)).place(x=current_x, y=current_y)
        self.hit_rate = StringVar()
        hit_rate_entry = Entry(self, width=6, textvariable=self.hit_rate, font=(SCP, 12), justify=CENTER)
        hit_rate_entry.place(x=current_x + 2, y=current_y + current_y_diff)
        hit_rate_entry.bind("<Return>", lambda x: active_factor_entry.focus_set())

        current_x += 83
        Label(self, width=8, text="Cri.Ratio", font=(SCP, 10)).place(x=current_x, y=current_y + 3)
        self.critical_ratio = StringVar()
        critical_ratio_entry = Entry(self, width=6, textvariable=self.critical_ratio, font=(SCP, 12), justify=CENTER)
        critical_ratio_entry.place(x=current_x + 3, y=current_y + current_y_diff)
        critical_ratio_entry.bind("<Return>", lambda x: active_factor_entry.focus_set())

        current_x += 85
        Label(self, width=9, text="Cri.Factor", font=(SCP, 9)).place(x=current_x, y=current_y + 4)
        self.critical_factor = StringVar()
        critical_factor_entry = Entry(self, width=6, textvariable=self.critical_factor, font=(SCP, 12), justify=CENTER)
        critical_factor_entry.place(x=current_x + 3, y=current_y + current_y_diff)
        critical_factor_entry.bind("<Return>", lambda x: active_factor_entry.focus_set())

        current_x += 84
        Label(self, width=9, text="Act.Factor", font=(SCP, 9)).place(x=current_x, y=current_y + 4)
        self.active_factor = StringVar()
        active_factor_entry = Entry(self, width=6, textvariable=self.active_factor, font=(SCP, 12), justify=CENTER)
        active_factor_entry.place(x=current_x + 4, y=current_y + current_y_diff)
        active_factor_entry.bind("<Return>", lambda x: addition_entry.focus_set())

        current_x += 86
        Label(self, width=8, text="Act.Cost", font=(SCP, 11)).place(x=current_x, y=current_y + 3)
        self.active_cost = StringVar()
        active_cost_entry = Entry(self, width=6, textvariable=self.active_cost, font=(SCP, 12), justify=CENTER)
        active_cost_entry.place(x=current_x + 5, y=current_y + current_y_diff)
        active_cost_entry.bind("<Return>", lambda x: addition_entry.focus_set())

        # 送出、取消的按鈕
        current_y += 23 + current_y_diff * 2
        self.presently = ToggleButton(self, text="Presently", width=9, font=(SCP, 11), relief=RIDGE)
        self.presently.place(x=22, y=current_y)
        self.presently.bind("<space>", lambda event: self.presently.toggling())
        self.presently.bind("<Return>", lambda x: self.submitting())
        Button(self, text="Submit", command=self.submitting, width=28, relief=RIDGE, font=(SCP, 11)).place(
            x=131, y=current_y
        )
        Button(self, text="Cancel", command=self.destroy, width=13, relief=RIDGE, font=(SCP, 11)).place(
            x=405, y=current_y
        )

    def _init_content(self):
        self.atk.set(self.character_power.atk)
        self.level.set(self.character_power.level)
        self.atk_raised.set(self.character_power.atk_raised)
        self.hit_rate.set(self.character_power.hit_rate)
        self.critical_ratio.set(self.character_power.critical_ratio)
        self.critical_factor.set(self.character_power.critical_factor)
        self.active_factor.set(self.character_power.active_factor)
        self.active_cost.set(self.character_power.active_cost)
        self.addition.set(self.character_power.addition)
        self.presently.set_is_selected(self.character_power.presently)

    def submitting(self):
        self.character_power.character = self.character_selector.get()
        self.character_power.atk = int(self.atk.get())
        self.character_power.level = int(self.level.get())
        self.character_power.atk_raised = float(self.atk_raised.get())
        self.character_power.hit_rate = float(self.hit_rate.get())
        self.character_power.critical_ratio = float(self.critical_ratio.get())
        self.character_power.critical_factor = float(self.critical_factor.get())
        self.character_power.active_factor = float(self.active_factor.get())
        self.character_power.active_cost = int(self.active_cost.get())
        self.character_power.addition = self.addition.get()
        self.character_power.presently = self.presently.is_selected
        self.callback()
        self.destroy()

    def filling_in_entries_by_character(self):
        character = self.character_selector.get()

        self.atk_raised.set(1.0)
        self.hit_rate.set(character.atk_speed)
        self.critical_ratio.set(character.critical_rate)
        self.critical_factor.set(1.5)
        self.active_cost.set(character.active_cost)

    def filling_in_atk_by_level(self):
        atk = self.character_selector.get().estimate_atk_by_level(int(self.level.get()))
        if atk:
            self.atk.set(atk)

    def open_updating_character_window(self):
        open_updating_character_window(self.master, self.character_selector.get(), position_y_shift=-300)
예제 #4
0
class FriendInfoFrame(MainFrameWithTable):
    def __init__(self, master):
        MainFrameWithTable.__init__(self, master)
        self.model = FriendModel.FriendInfoModel()
        self.set_table_place(34, 29)
        self.table_model = TableModelAdvance()
        self.table_model.set_columns(FriendInfo.TABLE_VIEW_COLUMNS,
                                     main_column='UsedNames')
        self.table_view.setModel(self.table_model)
        # 滑鼠中鍵事件註冊,若為設定為更新好友資訊,並選取該列
        self.table_view.bind(
            "<Button-2>", lambda event:
            (self.table_view.handle_left_click(event),
             open_updating_friend_info_window(
                 self,
                 self.get_corresponding_friend_info_in_row(
                     self.table_view.get_row_clicked(event)), self.update_table
             )))

        self._init_left_frame()
        self._init_upper_frame()
        self.model.update_data()
        self.update_all()

    def _init_upper_frame(self):
        basic_y = 3

        basic_x = 52
        button = Button(self, text="新增好友", width=8, font=(MS_JH, 11))
        button.place(x=basic_x, y=-1)
        button["command"] = self.adding_new_friend

        basic_x = 153
        Label(self, text='Order:', font=(MS_JH, 12)).place(x=basic_x,
                                                           y=basic_y)
        self.order_selector = ttk.Combobox(self,
                                           state='readonly',
                                           width=10,
                                           justify=CENTER)
        self.order_selector.set(FriendInfo.TABLE_VIEW_SORTABLE_COLUMNS[0])
        self.order_selector['values'] = FriendInfo.TABLE_VIEW_SORTABLE_COLUMNS
        self.order_selector.place(x=basic_x + 55, y=basic_y + 1)
        self.order_selector.bind(
            '<<ComboboxSelected>>',
            lambda x: self.redisplay_table_by_order_rule())

        # 角色部分名稱篩選
        basic_x = 322
        Label(self, text='篩選:', font=(MS_JH, 12)).place(x=basic_x, y=basic_y)
        self.queried_name = StringVar()
        entry = Entry(self,
                      width=8,
                      textvariable=self.queried_name,
                      font=(MS_JH, 11))
        entry.place(x=basic_x + 42, y=basic_y + 2)
        entry.bind('<Return>', lambda x: self.update_table())

        basic_x = 460
        self.friend_count_var = StringVar()
        Label(self, textvariable=self.friend_count_var,
              font=(MS_JH, 12)).place(x=basic_x + 17, y=basic_y)

        basic_x = 565
        since_last_record = 'Since: {0} days ago'.format(
            FriendModel.get_since_all_record_date())
        Label(self, text=since_last_record,
              font=(MS_JH, 12)).place(x=basic_x + 17, y=basic_y)

    def _init_left_frame(self):
        button = Button(self,
                        text="記錄好友現況",
                        width=2,
                        height=12,
                        wraplength=1,
                        font=(MS_JH, 12))
        button.place(x=4, y=40)
        button["command"] = self.switching_to_friend_record

        self.friend_existent_mode_button = \
            ToggleButton(self, text="好友整理", width=2, height=5, wraplength=1, font=(MS_JH, 11))
        self.friend_existent_mode_button.place(x=5, y=304)
        self.friend_existent_mode_button[
            "command"] = self.switching_friend_existent_mode

    def update_all(self):
        self.update_friend_count_var()
        self.update_table()

    def update_table(self):
        # 將符合名稱篩選的好友加入欲呈現表格中
        self.table_model.set_rows(
            self.model.get_displaying_data(self.queried_name.get()))
        self.redisplay_table_by_order_rule()

    def redisplay_table_by_order_rule(self):
        # 先根據目前的選擇設定排序方法
        self.table_model.setSortOrder(columnName=self.order_selector.get())

        self.redisplay_table()

        self.table_view.hide_column('ID')
        self.table_view.hide_column('LastProfession')

        # 不限制會太寬,難以瀏覽全部資訊
        self.table_view.resizeColumn(1, 125)  # UsedNames
        self.table_view.resizeColumn(2, 90)  # Excellence
        self.table_view.resizeColumn(3, 75)  # Defect
        self.table_view.resizeColumn(4, 85)  # Relation
        self.table_view.resizeColumn(5, 70)  # Offline
        self.table_view.resizeColumn(6, 155)  # UsedCharacters

    def switching_to_friend_record(self):
        self.master.change_main_frame(FriendRecordFrame(self.master))

    def switching_friend_existent_mode(self):
        if self.friend_existent_mode_button.is_selected:
            pass
        else:
            self.model.clear_existed_ids()
            self.update_table()

    def update_friend_count_var(self):
        self.friend_count_var.set('Friends: %02d' %
                                  self.model.get_friend_number())  # 好友總數

    # 取得未使用的 ID,並將新好友指定到該 ID
    def adding_new_friend(self):
        self.model.try_adding_new_friend(
            lambda info, callback: open_updating_friend_info_window(
                self, info, lambda: (callback(), self.update_all())),
            lambda: tkMessageBox.showwarning(
                "Can not add any friend", '已達好友上限', parent=self))

    # 記錄該好友存在,或更改好友資訊,或顯示其歷史角色訊息
    def do_double_clicking(self, event):
        friend_info = self.get_corresponding_friend_info_in_row(
            self.table_view.get_row_clicked(event))
        if self.friend_existent_mode_button.is_selected:
            self.model.set_friend_existed(friend_info)
            self.queried_name.set('')  # 此時的篩選應是為了找此人,故處理後清空條件
            self.update_table()
        else:
            # 雙擊歷史角色欄位時顯示其訊息,否則更改好友資訊
            if self.table_view.get_col_clicked(event) == 6:
                tkMessageBox.showinfo("Characters",
                                      friend_info.used_characters,
                                      parent=self)
            else:
                open_updating_friend_info_window(self, friend_info,
                                                 self.update_table)

    def do_dragging_along_right(self, row_number):
        friend_info = self.get_corresponding_friend_info_in_row(row_number)
        delete_friend_with_conforming(
            self, friend_info, lambda:
            (self.callback_after_deleting_friend(friend_info)))

    def callback_after_deleting_friend(self, friend_info):
        self.model.remove(friend_info)  # 直接從 list 中拿掉,不用重撈
        self.update_friend_count_var()
        self.queried_name.set('')  # 此時的篩選應是為了找此人,故處理後清空條件
        self.update_table()

    def get_corresponding_friend_info_in_row(self, row_number):
        selected_id = self.table_model.getCellRecord(row_number, 0)
        return self.model.get_specific_datum('f_id', selected_id)
예제 #5
0
class MonthlyDroppedCanvas(Canvas):
    KEY_TOTAL = 'total'
    KEY_FERTILIZER = 'fertilizer'
    KEY_CHARACTER = 'character'

    def __init__(self, master, section, **kwargs):
        Canvas.__init__(self, master, **kwargs)
        self.title = StringVar()
        self.section = section
        self._init_frame()
        self._init_fields()

    def _init_frame(self):
        Label(self, textvariable=self.title, width=8, font=(MS_JH, 14)).place(x=43, y=5)
        self.box_12_button = ToggleButton(self, text='1&2', width=4, font=(SCP, 11), relief=RIDGE)
        self.box_12_button.place(x=18 + 51 * 0, y=39)
        self.box_3_button = ToggleButton(self, text='3', width=4, font=(SCP, 11), relief=RIDGE)
        self.box_3_button.place(x=18 + 51 * 1, y=39)
        self.box_4_button = ToggleButton(self, text='4', width=4, font=(SCP, 11), relief=RIDGE)
        self.box_4_button.place(x=18 + 51 * 2, y=39)

        submit_button = Button(self, text='Submit', width=15, font=(SCP, 11), relief=RIDGE)
        submit_button.place(x=20, y=76)
        submit_button.bind('<Button-1>', lambda event: self.submitting())

        label_x = 12
        var_x = label_x + 98
        current_y = 114
        Label(self, text='  Times   :', width=12, font=(SCP, 10)).place(x=label_x, y=current_y)
        Label(self, text='Fertilizer:', width=12, font=(SCP, 10)).place(x=label_x, y=current_y + 20)
        self.times_var = StringVar()
        self.fertilizer_var = StringVar()
        Label(self, textvariable=self.times_var, width=6, font=(SCP, 11)).place(x=var_x, y=current_y)
        Label(self, textvariable=self.fertilizer_var, width=6, font=(SCP, 11)).place(x=var_x, y=current_y + 20)

        current_y += 45
        Label(self, text=' Avg.Fer. :', width=12, font=(SCP, 10)).place(x=label_x, y=current_y)
        Label(self, text='Character :', width=12, font=(SCP, 10)).place(x=label_x, y=current_y + 20)
        self.avg_fertilizer_var = StringVar()
        self.character_var = StringVar()
        Label(self, textvariable=self.avg_fertilizer_var, width=6, font=(SCP, 11)).place(x=var_x, y=current_y)
        Label(self, textvariable=self.character_var, width=6, font=(SCP, 11)).place(x=var_x, y=current_y + 20)

        self._init_buttons_state()

    def _init_fields(self):
        data_record = get_data_record(self.section)
        self.title.set(data_record['title'])
        self.statistic_tacker = DroppedStatisticTacker(2)
        self.statistic_tacker.set(data_record[self.KEY_TOTAL],
                                  [data_record[self.KEY_FERTILIZER], data_record[self.KEY_CHARACTER]])

        self._update_statistics()

    def _update_statistics(self):
        self.times_var.set(self.statistic_tacker.times)
        self.fertilizer_var.set(self.statistic_tacker.drops[0])
        avg_count = self.statistic_tacker.get_statistics_count()
        self.avg_fertilizer_var.set('%.2f' % (avg_count[0]))
        self.character_var.set(' %.1f %%' % ((avg_count[1]) * 100))

    def _init_buttons_state(self):
        self.box_12_button.set_is_selected(True)
        self.box_3_button.set_is_selected(False)
        self.box_4_button.set_is_selected(False)

    def submitting(self):
        self.statistic_tacker.record([int(self.box_12_button.is_selected) * 2 + self.box_3_button.is_selected,
                                      self.box_4_button.is_selected])

        data_record = get_data_record(self.section)
        data_record[self.KEY_TOTAL] = self.statistic_tacker.times
        data_record[self.KEY_FERTILIZER] = self.statistic_tacker.drops[0]
        data_record[self.KEY_CHARACTER] = self.statistic_tacker.drops[1]
        save_data_record()

        self._init_buttons_state()
        self._update_statistics()
예제 #6
0
class FriendInfoFrame(MainFrameWithTable):
    def __init__(self, master):
        MainFrameWithTable.__init__(self, master)
        self.model = FriendModel.FriendInfoModel()
        self.set_table_place(34, 29)
        self.table_model = TableModelAdvance()
        self.table_model.set_columns(FriendInfo.TABLE_VIEW_COLUMNS, main_column='UsedNames')
        self.table_view.setModel(self.table_model)
        # 滑鼠中鍵事件註冊,若為設定為更新好友資訊,並選取該列
        self.table_view.bind("<Button-2>", lambda event: (
            self.table_view.handle_left_click(event),
            open_updating_friend_info_window(
                self, self.get_corresponding_friend_info_in_row(self.table_view.get_row_clicked(event)),
                self.update_table)))

        self._init_left_frame()
        self._init_upper_frame()
        self.model.update_data()
        self.update_all()

    def _init_upper_frame(self):
        basic_y = 3

        basic_x = 52
        button = Button(self, text="新增好友", width=8, font=(MS_JH, 11))
        button.place(x=basic_x, y=-1)
        button["command"] = self.adding_new_friend

        basic_x = 153
        Label(self, text='Order:', font=(MS_JH, 12)).place(x=basic_x, y=basic_y)
        self.order_selector = ttk.Combobox(self, state='readonly', width=10, justify=CENTER)
        self.order_selector.set(FriendInfo.TABLE_VIEW_SORTABLE_COLUMNS[0])
        self.order_selector['values'] = FriendInfo.TABLE_VIEW_SORTABLE_COLUMNS
        self.order_selector.place(x=basic_x + 55, y=basic_y + 1)
        self.order_selector.bind('<<ComboboxSelected>>', lambda x: self.redisplay_table_by_order_rule())

        # 角色部分名稱篩選
        basic_x = 322
        Label(self, text='篩選:', font=(MS_JH, 12)).place(x=basic_x, y=basic_y)
        self.queried_name = StringVar()
        entry = Entry(self, width=8, textvariable=self.queried_name, font=(MS_JH, 11))
        entry.place(x=basic_x + 42, y=basic_y + 2)
        entry.bind('<Return>', lambda x: self.update_table())

        basic_x = 460
        self.friend_count_var = StringVar()
        Label(self, textvariable=self.friend_count_var, font=(MS_JH, 12)).place(x=basic_x + 17, y=basic_y)

        basic_x = 565
        since_last_record = 'Since: {0} days ago'.format(FriendModel.get_since_all_record_date())
        Label(self, text=since_last_record, font=(MS_JH, 12)).place(x=basic_x + 17, y=basic_y)

    def _init_left_frame(self):
        button = Button(self, text="記錄好友現況", width=2, height=12, wraplength=1, font=(MS_JH, 12))
        button.place(x=4, y=40)
        button["command"] = self.switching_to_friend_record

        self.friend_existent_mode_button = \
            ToggleButton(self, text="好友整理", width=2, height=5, wraplength=1, font=(MS_JH, 11))
        self.friend_existent_mode_button.place(x=5, y=304)
        self.friend_existent_mode_button["command"] = self.switching_friend_existent_mode

    def update_all(self):
        self.update_friend_count_var()
        self.update_table()

    def update_table(self):
        # 將符合名稱篩選的好友加入欲呈現表格中
        self.table_model.set_rows(self.model.get_displaying_data(self.queried_name.get()))
        self.redisplay_table_by_order_rule()

    def redisplay_table_by_order_rule(self):
        # 先根據目前的選擇設定排序方法
        self.table_model.setSortOrder(columnName=self.order_selector.get())

        self.redisplay_table()

        self.table_view.hide_column('ID')
        self.table_view.hide_column('LastProfession')

        # 不限制會太寬,難以瀏覽全部資訊
        self.table_view.resizeColumn(1, 125)  # UsedNames
        self.table_view.resizeColumn(2, 90)  # Excellence
        self.table_view.resizeColumn(3, 75)  # Defect
        self.table_view.resizeColumn(4, 85)  # Relation
        self.table_view.resizeColumn(5, 70)  # Offline
        self.table_view.resizeColumn(6, 155)  # UsedCharacters

    def switching_to_friend_record(self):
        self.master.change_main_frame(FriendRecordFrame(self.master))

    def switching_friend_existent_mode(self):
        if self.friend_existent_mode_button.is_selected:
            pass
        else:
            self.model.clear_existed_ids()
            self.update_table()

    def update_friend_count_var(self):
        self.friend_count_var.set('Friends: %02d' % self.model.get_friend_number())  # 好友總數

    # 取得未使用的 ID,並將新好友指定到該 ID
    def adding_new_friend(self):
        self.model.try_adding_new_friend(
            lambda info, callback: open_updating_friend_info_window(
                self, info, lambda: (callback(), self.update_all())),
            lambda: tkMessageBox.showwarning("Can not add any friend", '已達好友上限', parent=self))

    # 記錄該好友存在,或更改好友資訊,或顯示其歷史角色訊息
    def do_double_clicking(self, event):
        friend_info = self.get_corresponding_friend_info_in_row(self.table_view.get_row_clicked(event))
        if self.friend_existent_mode_button.is_selected:
            self.model.set_friend_existed(friend_info)
            self.queried_name.set('')  # 此時的篩選應是為了找此人,故處理後清空條件
            self.update_table()
        else:
            # 雙擊歷史角色欄位時顯示其訊息,否則更改好友資訊
            if self.table_view.get_col_clicked(event) == 6:
                tkMessageBox.showinfo("Characters", friend_info.used_characters, parent=self)
            else:
                open_updating_friend_info_window(self, friend_info, self.update_table)

    def do_dragging_along_right(self, row_number):
        friend_info = self.get_corresponding_friend_info_in_row(row_number)
        delete_friend_with_conforming(self, friend_info,
                                      lambda: (self.callback_after_deleting_friend(friend_info)))

    def callback_after_deleting_friend(self, friend_info):
        self.model.remove(friend_info)  # 直接從 list 中拿掉,不用重撈
        self.update_friend_count_var()
        self.queried_name.set('')  # 此時的篩選應是為了找此人,故處理後清空條件
        self.update_table()

    def get_corresponding_friend_info_in_row(self, row_number):
        selected_id = self.table_model.getCellRecord(row_number, 0)
        return self.model.get_specific_datum('f_id', selected_id)
class CharacterPowerWindow(BasicWindow):
    def __init__(self,
                 master,
                 character_power,
                 callback,
                 width=558,
                 height=222,
                 **kwargs):
        BasicWindow.__init__(self,
                             master,
                             width=width,
                             height=height,
                             **kwargs)
        self.title('CharacterPower')
        self.character_power = character_power
        self.callback = callback
        self._init_widget()
        self._init_content()
        # 事件註冊,設定為更改角色詳細資訊
        self.bind("-", lambda event: self.open_updating_character_window())

    def _init_widget(self):
        current_y_diff = 28

        current_y = 20
        current_x = 23
        self.character_selector = CharacterSelectorCanvas(
            self, self.character_power.character)
        self.character_selector.place(x=current_x, y=current_y - 3)
        callback_after_selection = lambda event: (
            self.filling_in_entries_by_character(), level_entry.focus_set())
        self.character_selector.bind('<Return>', callback_after_selection)
        self.character_selector.bind('-', callback_after_selection)

        current_x += 145
        Label(self, width=5, text='Level', font=(SCP, 12)).place(x=current_x,
                                                                 y=current_y)
        self.level = StringVar()
        level_entry = Entry(self,
                            width=5,
                            textvariable=self.level,
                            font=(SCP, 12),
                            justify=CENTER)
        level_entry.place(x=current_x + 2, y=current_y + current_y_diff)
        level_entry.bind(
            '<Return>', lambda x:
            (self.filling_in_atk_by_level(), atk_entry.focus_set()))

        current_x += 62
        Label(self, width=5, text='Atk', font=(SCP, 12)).place(x=current_x,
                                                               y=current_y)
        self.atk = StringVar()
        atk_entry = Entry(self,
                          width=5,
                          textvariable=self.atk,
                          font=(SCP, 12),
                          justify=CENTER)
        atk_entry.place(x=current_x + 3, y=current_y + current_y_diff)
        atk_entry.bind('<Return>', lambda x: active_factor_entry.focus_set())

        current_x += 70
        Label(self, width=25, text='Addition',
              font=(SCP, 12)).place(x=current_x, y=current_y)
        self.addition = StringVar()
        addition_entry = Entry(self,
                               width=25,
                               textvariable=self.addition,
                               font=(MS_JH, 12),
                               justify=CENTER)
        addition_entry.place(x=current_x + 3, y=current_y + current_y_diff)
        addition_entry.bind('<Return>', lambda x: self.presently.focus_set())

        current_y += 14 + current_y_diff * 2
        current_x = 27
        Label(self, width=8, text='AtkRaised',
              font=(SCP, 10)).place(x=current_x + 1, y=current_y + 3)
        self.atk_raised = StringVar()
        atk_raised_entry = Entry(self,
                                 width=7,
                                 textvariable=self.atk_raised,
                                 font=(SCP, 12),
                                 justify=CENTER)
        atk_raised_entry.place(x=current_x, y=current_y + current_y_diff)
        atk_raised_entry.bind('<Return>',
                              lambda x: active_factor_entry.focus_set())

        current_x += 90
        Label(self, width=7, text='HitRate', font=(SCP, 11)).place(x=current_x,
                                                                   y=current_y)
        self.hit_rate = StringVar()
        hit_rate_entry = Entry(self,
                               width=6,
                               textvariable=self.hit_rate,
                               font=(SCP, 12),
                               justify=CENTER)
        hit_rate_entry.place(x=current_x + 2, y=current_y + current_y_diff)
        hit_rate_entry.bind('<Return>',
                            lambda x: active_factor_entry.focus_set())

        current_x += 83
        Label(self, width=8, text='Cri.Ratio',
              font=(SCP, 10)).place(x=current_x, y=current_y + 3)
        self.critical_ratio = StringVar()
        critical_ratio_entry = Entry(self,
                                     width=6,
                                     textvariable=self.critical_ratio,
                                     font=(SCP, 12),
                                     justify=CENTER)
        critical_ratio_entry.place(x=current_x + 3,
                                   y=current_y + current_y_diff)
        critical_ratio_entry.bind('<Return>',
                                  lambda x: active_factor_entry.focus_set())

        current_x += 85
        Label(self, width=9, text='Cri.Factor',
              font=(SCP, 9)).place(x=current_x, y=current_y + 4)
        self.critical_factor = StringVar()
        critical_factor_entry = Entry(self,
                                      width=6,
                                      textvariable=self.critical_factor,
                                      font=(SCP, 12),
                                      justify=CENTER)
        critical_factor_entry.place(x=current_x + 3,
                                    y=current_y + current_y_diff)
        critical_factor_entry.bind('<Return>',
                                   lambda x: active_factor_entry.focus_set())

        current_x += 84
        Label(self, width=9, text='Act.Factor',
              font=(SCP, 9)).place(x=current_x, y=current_y + 4)
        self.active_factor = StringVar()
        active_factor_entry = Entry(self,
                                    width=6,
                                    textvariable=self.active_factor,
                                    font=(SCP, 12),
                                    justify=CENTER)
        active_factor_entry.place(x=current_x + 4,
                                  y=current_y + current_y_diff)
        active_factor_entry.bind('<Return>',
                                 lambda x: addition_entry.focus_set())

        current_x += 86
        Label(self, width=8, text='Act.Cost',
              font=(SCP, 11)).place(x=current_x, y=current_y + 3)
        self.active_cost = StringVar()
        active_cost_entry = Entry(self,
                                  width=6,
                                  textvariable=self.active_cost,
                                  font=(SCP, 12),
                                  justify=CENTER)
        active_cost_entry.place(x=current_x + 5, y=current_y + current_y_diff)
        active_cost_entry.bind('<Return>',
                               lambda x: addition_entry.focus_set())

        # 送出、取消的按鈕
        current_y += 23 + current_y_diff * 2
        self.presently = ToggleButton(self,
                                      text='Presently',
                                      width=9,
                                      font=(SCP, 11),
                                      relief=RIDGE)
        self.presently.place(x=22, y=current_y)
        self.presently.bind('<space>', lambda event: self.presently.toggling())
        self.presently.bind('<Return>', lambda x: self.submitting())
        Button(self,
               text="Submit",
               command=self.submitting,
               width=28,
               relief=RIDGE,
               font=(SCP, 11)).place(x=131, y=current_y)
        Button(self,
               text="Cancel",
               command=self.destroy,
               width=13,
               relief=RIDGE,
               font=(SCP, 11)).place(x=405, y=current_y)

    def _init_content(self):
        self.atk.set(self.character_power.atk)
        self.level.set(self.character_power.level)
        self.atk_raised.set(self.character_power.atk_raised)
        self.hit_rate.set(self.character_power.hit_rate)
        self.critical_ratio.set(self.character_power.critical_ratio)
        self.critical_factor.set(self.character_power.critical_factor)
        self.active_factor.set(self.character_power.active_factor)
        self.active_cost.set(self.character_power.active_cost)
        self.addition.set(self.character_power.addition)
        self.presently.set_is_selected(self.character_power.presently)

    def submitting(self):
        self.character_power.character = self.character_selector.get()
        self.character_power.atk = int(self.atk.get())
        self.character_power.level = int(self.level.get())
        self.character_power.atk_raised = float(self.atk_raised.get())
        self.character_power.hit_rate = float(self.hit_rate.get())
        self.character_power.critical_ratio = float(self.critical_ratio.get())
        self.character_power.critical_factor = float(
            self.critical_factor.get())
        self.character_power.active_factor = float(self.active_factor.get())
        self.character_power.active_cost = int(self.active_cost.get())
        self.character_power.addition = self.addition.get()
        self.character_power.presently = self.presently.is_selected
        self.callback()
        self.destroy()

    def filling_in_entries_by_character(self):
        character = self.character_selector.get()

        self.atk_raised.set(1.0)
        self.hit_rate.set(character.atk_speed)
        self.critical_ratio.set(character.critical_rate)
        self.critical_factor.set(1.5)
        self.active_cost.set(character.active_cost)

    def filling_in_atk_by_level(self):
        atk = self.character_selector.get().estimate_atk_by_level(
            int(self.level.get()))
        if atk:
            self.atk.set(atk)

    def open_updating_character_window(self):
        open_updating_character_window(self.master,
                                       self.character_selector.get(),
                                       position_y_shift=-300)
예제 #8
0
class SpecificStageDroppedCanvas(Canvas):
    KEY_TITLE = 'title'
    KEY_TOTAL = 'total'
    KEY_DROPS = "drops"
    KEY_VALUES = "values"
    KEY_DEFAULTS = "defaults"

    def __init__(self, master, section, **kwargs):
        Canvas.__init__(self, master, **kwargs)
        self.title = StringVar()
        self.section = section
        self._init_frame()
        self._init_fields()

    def _init_frame(self):
        Label(self, textvariable=self.title, width=13,
              font=(MS_JH, 14)).place(x=12, y=5)
        self.box_1_button = ToggleButton(self,
                                         text='1st',
                                         width=3,
                                         font=(SCP, 11),
                                         relief=RIDGE)
        self.box_1_button.place(x=5 + 43 * 0, y=39)
        self.box_2_button = ToggleButton(self,
                                         text='2nd',
                                         width=3,
                                         font=(SCP, 11),
                                         relief=RIDGE)
        self.box_2_button.place(x=5 + 43 * 1, y=39)
        self.box_3_button = ToggleButton(self,
                                         text='3rd',
                                         width=3,
                                         font=(SCP, 11),
                                         relief=RIDGE)
        self.box_3_button.place(x=5 + 43 * 2, y=39)
        self.box_4_button = ToggleButton(self,
                                         text='4th',
                                         width=3,
                                         font=(SCP, 11),
                                         relief=RIDGE)
        self.box_4_button.place(x=5 + 43 * 3, y=39)

        submit_button = Button(self,
                               text='Submit',
                               width=17,
                               font=(SCP, 11),
                               relief=RIDGE)
        submit_button.place(x=5, y=76)
        submit_button.bind('<Button-1>', lambda event: self.submitting())

        current_y = 114
        self.total_desc = StringVar()
        Label(self, textvariable=self.total_desc, width=16,
              font=(SCP, 11)).place(x=13, y=current_y)
        current_y += 28
        self.drop_vars = [IntVar(), IntVar(), IntVar(), IntVar()]
        for i in range(4):
            Label(self, textvariable=self.drop_vars[i], width=3, font=(SCP, 11), relief=GROOVE). \
                place(x=6 + 43 * i, y=current_y)
        current_y += 29
        self.values_desc = StringVar()
        Label(self, textvariable=self.values_desc, width=16,
              font=(SCP, 11)).place(x=13, y=current_y)

    def _init_fields(self):
        data_record = get_data_record(self.section)
        self.title.set(data_record[self.KEY_TITLE])
        self.statistic_tacker = DroppedStatisticTacker(4)
        self.statistic_tacker.set(data_record[self.KEY_TOTAL],
                                  data_record[self.KEY_DROPS])
        self.values = data_record[self.KEY_VALUES]

        self._init_buttons_state(data_record[self.KEY_DEFAULTS])
        self._update_statistics()

    def _update_statistics(self):
        from itertools import izip

        self.total_desc.set('Times : %2d ' % self.statistic_tacker.times)
        for i in range(4):
            self.drop_vars[i].set(self.statistic_tacker.drops[i])
        self.values_desc.set('Value : %1.2f' % (sum(p * q for p, q in izip(
            self.values, self.statistic_tacker.get_statistics_ratio())) / 100))

    def _init_buttons_state(self, defaults):
        self.box_1_button.set_is_selected(defaults[0])
        self.box_2_button.set_is_selected(defaults[1])
        self.box_3_button.set_is_selected(defaults[2])
        self.box_4_button.set_is_selected(defaults[3])

    def submitting(self):
        self.statistic_tacker.record([
            self.box_1_button.is_selected, self.box_2_button.is_selected,
            self.box_3_button.is_selected, self.box_4_button.is_selected
        ])

        data_record = get_data_record(self.section)
        data_record[self.KEY_TOTAL] = self.statistic_tacker.times
        data_record[self.KEY_DROPS] = self.statistic_tacker.drops
        save_data_record()

        self._init_buttons_state(data_record[self.KEY_DEFAULTS])
        self._update_statistics()
예제 #9
0
class MonthlyDroppedCanvas(Canvas):
    KEY_TOTAL = 'total'
    KEY_FERTILIZER = 'fertilizer'
    KEY_CHARACTER = 'character'

    def __init__(self, master, section, **kwargs):
        Canvas.__init__(self, master, **kwargs)
        self.title = StringVar()
        self.section = section
        self._init_frame()
        self._init_fields()

    def _init_frame(self):
        Label(self, textvariable=self.title, width=8,
              font=(MS_JH, 14)).place(x=43, y=5)
        self.box_12_button = ToggleButton(self,
                                          text='1&2',
                                          width=4,
                                          font=(SCP, 11),
                                          relief=RIDGE)
        self.box_12_button.place(x=18 + 51 * 0, y=39)
        self.box_3_button = ToggleButton(self,
                                         text='3',
                                         width=4,
                                         font=(SCP, 11),
                                         relief=RIDGE)
        self.box_3_button.place(x=18 + 51 * 1, y=39)
        self.box_4_button = ToggleButton(self,
                                         text='4',
                                         width=4,
                                         font=(SCP, 11),
                                         relief=RIDGE)
        self.box_4_button.place(x=18 + 51 * 2, y=39)

        submit_button = Button(self,
                               text='Submit',
                               width=15,
                               font=(SCP, 11),
                               relief=RIDGE)
        submit_button.place(x=20, y=76)
        submit_button.bind('<Button-1>', lambda event: self.submitting())

        label_x = 12
        var_x = label_x + 98
        current_y = 114
        Label(self, text='  Times   :', width=12,
              font=(SCP, 10)).place(x=label_x, y=current_y)
        Label(self, text='Fertilizer:', width=12,
              font=(SCP, 10)).place(x=label_x, y=current_y + 20)
        self.times_var = StringVar()
        self.fertilizer_var = StringVar()
        Label(self, textvariable=self.times_var, width=6,
              font=(SCP, 11)).place(x=var_x, y=current_y)
        Label(self, textvariable=self.fertilizer_var, width=6,
              font=(SCP, 11)).place(x=var_x, y=current_y + 20)

        current_y += 45
        Label(self, text=' Avg.Fer. :', width=12,
              font=(SCP, 10)).place(x=label_x, y=current_y)
        Label(self, text='Character :', width=12,
              font=(SCP, 10)).place(x=label_x, y=current_y + 20)
        self.avg_fertilizer_var = StringVar()
        self.character_var = StringVar()
        Label(self,
              textvariable=self.avg_fertilizer_var,
              width=6,
              font=(SCP, 11)).place(x=var_x, y=current_y)
        Label(self, textvariable=self.character_var, width=6,
              font=(SCP, 11)).place(x=var_x, y=current_y + 20)

        self._init_buttons_state()

    def _init_fields(self):
        data_record = get_data_record(self.section)
        self.title.set(data_record['title'])
        self.statistic_tacker = DroppedStatisticTacker(2)
        self.statistic_tacker.set(data_record[self.KEY_TOTAL], [
            data_record[self.KEY_FERTILIZER], data_record[self.KEY_CHARACTER]
        ])

        self._update_statistics()

    def _update_statistics(self):
        self.times_var.set(self.statistic_tacker.times)
        self.fertilizer_var.set(self.statistic_tacker.drops[0])
        avg_count = self.statistic_tacker.get_statistics_count()
        self.avg_fertilizer_var.set('%.2f' % (avg_count[0]))
        self.character_var.set(' %.1f %%' % ((avg_count[1]) * 100))

    def _init_buttons_state(self):
        self.box_12_button.set_is_selected(True)
        self.box_3_button.set_is_selected(False)
        self.box_4_button.set_is_selected(False)

    def submitting(self):
        self.statistic_tacker.record([
            int(self.box_12_button.is_selected) * 2 +
            self.box_3_button.is_selected, self.box_4_button.is_selected
        ])

        data_record = get_data_record(self.section)
        data_record[self.KEY_TOTAL] = self.statistic_tacker.times
        data_record[self.KEY_FERTILIZER] = self.statistic_tacker.drops[0]
        data_record[self.KEY_CHARACTER] = self.statistic_tacker.drops[1]
        save_data_record()

        self._init_buttons_state()
        self._update_statistics()
class CharacterWeaponFrame(MainFrameWithTable):
    def __init__(self, master, **kwargs):
        MainFrameWithTable.__init__(self, master, **kwargs)
        # 滑鼠中鍵事件註冊,設定為更改角色詳細資訊,並選取該列
        self.table_view.bind("<Button-2>", lambda event: self.opening_character_update_window(event))
        self.set_table_place(6, 31)
        self.filter_manager = FilterRuleManager()
        self.table_model = TableModelAdvance()
        self.table_model.set_columns(CharacterWeapon.TABLE_VIEW_COLUMNS)
        self.table_view.setModel(self.table_model)

        self.characters = CharacterWeaponModel.select_character_weapon_list()
        self._init_upper_frame()
        self.update_table()

    def _init_upper_frame(self):
        self.insufficiently = ToggleButton(self, text='Insufficiently', width=14, font=(SCP, 8), relief=RIDGE)
        self.insufficiently.bind('<Button-1>', lambda event: (
            self.filter_manager.set_specific_condition(
                'unforged', 0 if self.insufficiently.is_selected else CONDITIONLESS, rule=not_match_request),
            self.update_table()), add='+')
        self.insufficiently.place(x=380, y=3)

        Label(self, text='Type:', width=5, font=(MS_JH, 11)).place(x=510, y=3)
        self.type_selector = FilteredCombobox(self, width=4, font=(MS_JH, 9), justify=CENTER, state='readonly')
        self.type_selector['values'] = WEAPONS
        self.type_selector.place(x=558, y=5)
        self.type_selector.bind('<<ComboboxSelected>>', lambda event: (
            self.filter_manager.set_specific_condition('weapon_type', self.type_selector.get()), self.update_table()))

        button = Button(self, text='新增', width=8, font=(MS_JH, 10))
        button.place(x=640, y=1)
        button["command"] = lambda: open_adding_new_character_weapon_window(
            self, callback=lambda cw: (self.characters.append(cw), self.update_table()))

    def update_table(self):
        results = self.filter_manager.filter(self.characters)
        self.table_model.set_rows([result.get_table_view_info() for result in results])
        self.table_model.setSortOrder(columnName='Left', reverse=1)
        self.redisplay_table()

    # 更改角色資訊
    def opening_character_update_window(self, event):
        self.table_view.handle_left_click(event)
        character = self.get_corresponding_character_weapon_in_row(self.table_view.get_row_clicked(event)).character
        open_updating_character_window(self, character, lambda: None)

    # 編輯武器狀態
    def do_double_clicking(self, event):
        character_weapon = self.get_corresponding_character_weapon_in_row(self.table_view.get_row_clicked(event))
        open_updating_character_weapon_window(self, character_weapon, self.update_table)

    def do_dragging_along_right(self, row_number):
        character = self.get_corresponding_character_weapon_in_row(row_number)
        delete_character_weapon_with_conforming(self, character, lambda: (
            self.characters.remove(character), self.update_table()))  # 直接從 list 中拿掉,不用重撈

    def get_corresponding_character_weapon_in_row(self, row_number):
        selected_name = self.table_model.getCellRecord(row_number, 0)
        for character in self.characters:
            if character.nickname.encode('utf-8') == selected_name:
                return character