Пример #1
0
    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()))
Пример #2
0
    def _init_upper_frame(self):
        filter_frame = Frame(self, width=self["width"], height=40)
        filter_frame.place(x=0, y=0)

        current_x = 45
        self.profession_selector = ProfessionSelector(filter_frame, self.updating_profession)
        self.profession_selector.place(x=current_x, y=-4)

        current_x += 199
        self.rank_selector = RankSelector(filter_frame, self.updating_rank)
        self.rank_selector.place(x=current_x, y=-4)

        # 所屬篩選
        current_x = 448
        Label(filter_frame, text="所屬:", font=(MS_JH, 10)).place(x=current_x + 10, y=-3)
        self.belonged = FilteredCombobox(filter_frame, width=6, justify=CENTER)
        self.belonged["values"] = BELONGEDS
        self.belonged.place(x=current_x, y=16)
        self.belonged.bind("<<ComboboxSelected>>", lambda event: self.updating_belonged())

        # 角色部分名稱篩選
        current_x += 75
        Label(filter_frame, text="篩選:", font=(MS_JH, 12)).place(x=current_x, y=7)
        self.request = StringVar()
        entry = Entry(filter_frame, width=9, textvariable=self.request, font=(MS_JH, 11))
        entry.place(x=current_x + 42, y=9)
        entry.bind("<Return>", lambda event: self.update_table())

        # 清空進行篩選的條件
        button = Button(filter_frame, text="清空條件", width=7, font=(MS_JH, 11))
        button.place(x=667, y=3)
        button["command"] = self.clearing_filters
Пример #3
0
    def _init_widgets(self):
        self.profession_selector = ProfessionSelector(self, self.updating_request_profession)
        self.profession_selector.place(x=5, y=5)
        self.rank_selector = RankSelector(self, self.updating_request_rank)
        self.rank_selector.place(x=5, y=53)

        Label(self, text='所屬', width=5, font=("", 10)).place(x=221, y=5)
        self.belonged_selector = FilteredCombobox(self, width=7, font=("", 11), justify=CENTER)
        self.belonged_selector['values'] = BELONGEDS
        self.belonged_selector.place(x=213, y=22)
        self.belonged_selector.bind('<<ComboboxSelected>>',
                                    lambda x: self.updating_request_belonged(self.belonged_selector.get()))
        self.belonged_selector.bind('<Return>', lambda x: self.character_selector.focus_set())

        Label(self, text='篩選', width=5, font=("", 11)).place(x=222, y=54)
        self.name_request = StringVar(value='')
        entry = Entry(self, width=8, textvariable=self.name_request, font=("", 12))
        entry.place(x=214, y=73)
        entry.bind('<Return>', lambda x: self.updating_request_name())
        entry.bind('<Escape>', lambda x: (self.name_request.set(''), self.updating_request_name()))

        Label(self, text='Character', width=10, font=("", 12)).place(x=304, y=26)
        self.character_selector = ttk.Combobox(self, state='readonly', width=10, font=("", 12), justify=CENTER)
        self.character_selector.place(x=305, y=48)
        self.character_selector.bind('<Return>', lambda x: self.submitting())

        # 熱鍵,直接指過來
        self.bind('<f>', lambda x: self.character_selector.focus_set())

        y_position = 115
        # 送交的按鈕
        button = Button(self, text="選擇此角色", width=25, borderwidth=3)
        button.place(x=17, y=y_position)
        button["command"] = self.submitting

        # 新增角色的按鈕
        button = Button(self, text="新增角色", width=9, borderwidth=3)
        button.place(x=225, y=y_position)
        button["command"] = lambda: open_adding_new_jp_character_window(
            self, lambda new_character: (self.update_records(), self.updating_character_selector()))

        # 取消並結束的按鈕
        button = Button(self, text="放棄選擇", width=9, borderwidth=3)
        button.place(x=317, y=y_position)
        button["command"] = self.destroy
Пример #4
0
    def _init_upper_frame(self):
        filter_frame = Frame(self, width=self['width'], height=40)
        filter_frame.place(x=0, y=0)

        current_x = 45
        self.profession_selector = ProfessionSelector(filter_frame,
                                                      self.updating_profession)
        self.profession_selector.place(x=current_x, y=-4)

        current_x += 199
        self.rank_selector = RankSelector(filter_frame, self.updating_rank)
        self.rank_selector.place(x=current_x, y=-4)

        # 所屬篩選
        current_x = 448
        Label(filter_frame, text='所屬:',
              font=(MS_JH, 10)).place(x=current_x + 10, y=-3)
        self.belonged = FilteredCombobox(filter_frame, width=6, justify=CENTER)
        self.belonged['values'] = BELONGEDS
        self.belonged.place(x=current_x, y=16)
        self.belonged.bind('<<ComboboxSelected>>',
                           lambda event: self.updating_belonged())

        # 角色部分名稱篩選
        current_x += 75
        Label(filter_frame, text='篩選:', font=(MS_JH, 12)).place(x=current_x,
                                                                y=7)
        self.request = StringVar()
        entry = Entry(filter_frame,
                      width=9,
                      textvariable=self.request,
                      font=(MS_JH, 11))
        entry.place(x=current_x + 42, y=9)
        entry.bind('<Return>', lambda event: self.update_table())

        # 清空進行篩選的條件
        button = Button(filter_frame, text="清空條件", width=7, font=(MS_JH, 11))
        button.place(x=667, y=3)
        button["command"] = self.clearing_filters
    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()))
Пример #6
0
    def _init_filter_frame(self):
        basic_x = 20
        Label(self, text='E:', font=(MS_JH, 12)).place(x=basic_x, y=3)
        self.event_filter = FilteredObjectCombobox(self,
                                                   setter=lambda obj: obj.name,
                                                   getter=lambda obj: obj.e_id,
                                                   width=16,
                                                   justify=CENTER)
        self.event_filter.set_objects(self.events)
        self.event_filter.place(x=basic_x + 18, y=3)
        self.event_filter.bind(
            '<<ComboboxSelected>>',
            lambda x: (self.filter_manager.set_specific_condition(
                'event_id', self.event_filter.get()), self.update_table()),
            add='+')
        self.event_filter.bind(
            '<Button-2>', lambda event: (open_updating_event_window(
                self, self.event_filter.selected_object, lambda: self.
                event_filter.set_objects(self.events))))

        basic_x += 158
        Label(self, text='C:', font=(MS_JH, 12)).place(x=basic_x, y=3)
        self.cost_filter = FilteredCombobox(self, width=6, justify=CENTER)
        self.cost_filter['values'] = DRAW_LOTS_COST
        self.cost_filter.place(x=basic_x + 20, y=3)
        self.cost_filter.bind(
            '<<ComboboxSelected>>', lambda x:
            (self.filter_manager.set_specific_condition(
                'cost', self.cost_filter.get()), self.update_table()))

        basic_x += 90
        Label(self, text='R:', font=(MS_JH, 12)).place(x=basic_x, y=3)
        self.rank_filter = IntFilteredCombobox(self, width=3, justify=CENTER)
        self.rank_filter['values'] = [5, 4, 3]
        self.rank_filter.place(x=basic_x + 20, y=3)
        self.rank_filter.bind(
            '<<ComboboxSelected>>', lambda x:
            (self.filter_manager.set_specific_condition(
                'rank', self.rank_filter.get()), self.update_table()))

        basic_x = 342
        Label(self, text='Total:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.total_count = Label(self, font=(MS_JH, 12))
        self.total_count.place(x=basic_x + 44, y=2)

        basic_x += 83
        Label(self, text='SSR:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.ssr_count = Label(self, font=(MS_JH, 10))
        self.ssr_count.place(x=basic_x + 34, y=-3)
        self.ssr_ratio = Label(self, font=(MS_JH, 9))
        self.ssr_ratio.place(x=basic_x + 44, y=13)

        basic_x += 80
        Label(self, text='SR:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.sr_count = Label(self, font=(MS_JH, 10))
        self.sr_count.place(x=basic_x + 25, y=-3)
        self.sr_ratio = Label(self, font=(MS_JH, 9))
        self.sr_ratio.place(x=basic_x + 35, y=13)

        basic_x += 78
        Label(self, text='R:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.r_count = Label(self, font=(MS_JH, 10))
        self.r_count.place(x=basic_x + 16, y=-3)
        self.r_ratio = Label(self, font=(MS_JH, 9))
        self.r_ratio.place(x=basic_x + 26, y=13)

        # 清空進行篩選的條件
        button = Button(self, text="清空條件", width=7, font=(MS_JH, 11))
        button.place(x=658, y=-1)
        button["command"] = self.clearing_filter
Пример #7
0
class DrawLotsFrame(MainFrameWithTable):
    def __init__(self, master, **kwargs):
        MainFrameWithTable.__init__(self, master, **kwargs)
        self.set_table_place(34, 29)
        self.table_model = TableModelAdvance()
        self.table_model.set_columns(RecordOfDrawLots.TABLE_VIEW_COLUMNS)
        # 滑鼠中鍵事件註冊,設定為更改角色詳細資訊,並選取該列
        self.table_view.bind(
            "<Button-2>",
            lambda event: self.opening_character_update_window(event))
        self.table_view.setModel(self.table_model)

        self.filter_manager = FilterRuleManager()
        self.records = DrawLotsModel.select_record_list()
        self.events = DrawLotsModel.select_event_list()

        self._init_adding_frame()
        self._init_filter_frame()

        self.table.tkraise()  # 放上層,避免被其他元件遮到
        self.update_table()

    def _init_adding_frame(self):
        # 新增酒廠的按鈕
        button = Button(self,
                        text="新增酒廠",
                        width=2,
                        height=5,
                        wraplength=1,
                        font=(MS_JH, 11))
        button.place(x=7, y=41)
        button["command"] = lambda: open_adding_event_window(
            self, lambda event: (self.events.insert(0, event),
                                 self.event_filter.set_objects(self.events)))

        # 新增記錄的按鈕
        button = Button(self,
                        text="新增記錄",
                        width=2,
                        height=12,
                        wraplength=1,
                        font=(MS_JH, 12))
        button.place(x=5, y=155)
        button['command'] = self.adding_record
        button.bind('<Button-3>',
                    lambda event: self.adding_record(limitation=False))

    def _init_filter_frame(self):
        basic_x = 20
        Label(self, text='E:', font=(MS_JH, 12)).place(x=basic_x, y=3)
        self.event_filter = FilteredObjectCombobox(self,
                                                   setter=lambda obj: obj.name,
                                                   getter=lambda obj: obj.e_id,
                                                   width=16,
                                                   justify=CENTER)
        self.event_filter.set_objects(self.events)
        self.event_filter.place(x=basic_x + 18, y=3)
        self.event_filter.bind(
            '<<ComboboxSelected>>',
            lambda x: (self.filter_manager.set_specific_condition(
                'event_id', self.event_filter.get()), self.update_table()),
            add='+')
        self.event_filter.bind(
            '<Button-2>', lambda event: (open_updating_event_window(
                self, self.event_filter.selected_object, lambda: self.
                event_filter.set_objects(self.events))))

        basic_x += 158
        Label(self, text='C:', font=(MS_JH, 12)).place(x=basic_x, y=3)
        self.cost_filter = FilteredCombobox(self, width=6, justify=CENTER)
        self.cost_filter['values'] = DRAW_LOTS_COST
        self.cost_filter.place(x=basic_x + 20, y=3)
        self.cost_filter.bind(
            '<<ComboboxSelected>>', lambda x:
            (self.filter_manager.set_specific_condition(
                'cost', self.cost_filter.get()), self.update_table()))

        basic_x += 90
        Label(self, text='R:', font=(MS_JH, 12)).place(x=basic_x, y=3)
        self.rank_filter = IntFilteredCombobox(self, width=3, justify=CENTER)
        self.rank_filter['values'] = [5, 4, 3]
        self.rank_filter.place(x=basic_x + 20, y=3)
        self.rank_filter.bind(
            '<<ComboboxSelected>>', lambda x:
            (self.filter_manager.set_specific_condition(
                'rank', self.rank_filter.get()), self.update_table()))

        basic_x = 342
        Label(self, text='Total:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.total_count = Label(self, font=(MS_JH, 12))
        self.total_count.place(x=basic_x + 44, y=2)

        basic_x += 83
        Label(self, text='SSR:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.ssr_count = Label(self, font=(MS_JH, 10))
        self.ssr_count.place(x=basic_x + 34, y=-3)
        self.ssr_ratio = Label(self, font=(MS_JH, 9))
        self.ssr_ratio.place(x=basic_x + 44, y=13)

        basic_x += 80
        Label(self, text='SR:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.sr_count = Label(self, font=(MS_JH, 10))
        self.sr_count.place(x=basic_x + 25, y=-3)
        self.sr_ratio = Label(self, font=(MS_JH, 9))
        self.sr_ratio.place(x=basic_x + 35, y=13)

        basic_x += 78
        Label(self, text='R:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.r_count = Label(self, font=(MS_JH, 10))
        self.r_count.place(x=basic_x + 16, y=-3)
        self.r_ratio = Label(self, font=(MS_JH, 9))
        self.r_ratio.place(x=basic_x + 26, y=13)

        # 清空進行篩選的條件
        button = Button(self, text="清空條件", width=7, font=(MS_JH, 11))
        button.place(x=658, y=-1)
        button["command"] = self.clearing_filter

    def update_table(self):
        results = self.filter_manager.filter(self.records)
        self.table_model.set_rows(
            [result.get_table_view_info() for result in results])
        self.table_model.setSortOrder(columnName='Order', reverse=1)
        self.redisplay_table()
        self.table_view.resizeColumn(0, 55)  # DrawOrder
        self.table_view.resizeColumn(1, 178)  # Event
        self.table_view.resizeColumn(4, 120)  # Character

        # 就篩選結果更新統計資料
        self._update_statistic_by_specific_results(results)

    def _update_statistic_by_specific_results(self, results):
        # doing statistic: total, ssr, sr, r
        statistic = [0, 0, 0, 0]
        for record in results:
            record.take_statistic(statistic)

        # 特殊情況,顯示為 0 並結束
        if statistic[0] == 0:
            self.total_count["text"] = 0
            self.ssr_count["text"] = 0
            self.ssr_ratio["text"] = 0
            self.sr_count["text"] = 0
            self.sr_ratio["text"] = 0
            self.r_count["text"] = 0
            self.r_ratio["text"] = 0
            return

        self.total_count["text"] = '%3d' % statistic[0]
        self.ssr_count["text"] = statistic[1]
        self.ssr_ratio["text"] = self.convert_to_ratio(statistic[0],
                                                       statistic[1])
        self.sr_count["text"] = statistic[2]
        self.sr_ratio["text"] = self.convert_to_ratio(statistic[0],
                                                      statistic[2])
        self.r_count["text"] = statistic[3]
        self.r_ratio["text"] = self.convert_to_ratio(statistic[0],
                                                     statistic[3])

    @staticmethod
    def convert_to_ratio(total, numerator):
        ratio = round(100.0 * numerator / total, 1)
        return str(ratio) + '%'

    def clearing_filter(self):
        self.event_filter.set(None)
        self.cost_filter.set('')
        self.rank_filter.set('')
        self.filter_manager.clean_specific_condition()
        self.update_table()

    def adding_record(self, limitation=True):
        open_adding_new_record_window(
            self, DrawLotsModel.get_suitable_events(self.events, limitation),
            lambda record: (self.records.append(record), self.update_table()))

    def do_double_clicking(self, event):
        record = self.get_record_by_order(
            self.table_model.getCellRecord(
                self.table_view.get_row_clicked(event), 0))
        open_updating_record_window(self,
                                    record,
                                    self.events,
                                    callback=self.update_table)

    def do_dragging_along_right(self, row_number):
        record = self.get_record_by_order(
            self.table_model.getCellRecord(row_number, 0))
        delete_record_with_conforming(
            self, record, lambda: (self.records.remove(record),
                                   self.update_table()))  # 直接從 list 中拿掉,不用重撈)

    def get_record_by_order(self, order):
        for each_record in self.records:
            if each_record.order == order:
                return each_record

    # 更改角色資訊
    def opening_character_update_window(self, event):
        self.table_view.handle_left_click(event)
        character = self.get_record_by_order(
            self.table_model.getCellRecord(
                self.table_view.get_row_clicked(event), 0)).character
        open_updating_character_window(self, character, lambda: None)
Пример #8
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
Пример #9
0
    def _init_filter_frame(self):
        basic_x = 20
        Label(self, text='E:', font=(MS_JH, 12)).place(x=basic_x, y=3)
        self.event_filter = FilteredObjectCombobox(
            self, setter=lambda obj: obj.name, getter=lambda obj: obj.e_id, width=16, justify=CENTER)
        self.event_filter.set_objects(self.events)
        self.event_filter.place(x=basic_x + 18, y=3)
        self.event_filter.bind('<<ComboboxSelected>>',
                               lambda x: (self.filter_manager.set_specific_condition(
                                   'event_id', self.event_filter.get()), self.update_table()), add='+')
        self.event_filter.bind('<Button-2>', lambda event: (open_updating_event_window(
            self, self.event_filter.selected_object, lambda: self.event_filter.set_objects(self.events))))

        basic_x += 158
        Label(self, text='C:', font=(MS_JH, 12)).place(x=basic_x, y=3)
        self.cost_filter = FilteredCombobox(self, width=6, justify=CENTER)
        self.cost_filter['values'] = DRAW_LOTS_COST
        self.cost_filter.place(x=basic_x + 20, y=3)
        self.cost_filter.bind('<<ComboboxSelected>>',
                              lambda x: (self.filter_manager.set_specific_condition('cost', self.cost_filter.get()),
                                         self.update_table()))

        basic_x += 90
        Label(self, text='R:', font=(MS_JH, 12)).place(x=basic_x, y=3)
        self.rank_filter = IntFilteredCombobox(self, width=3, justify=CENTER)
        self.rank_filter['values'] = [5, 4, 3]
        self.rank_filter.place(x=basic_x + 20, y=3)
        self.rank_filter.bind('<<ComboboxSelected>>',
                              lambda x: (self.filter_manager.set_specific_condition('rank', self.rank_filter.get()),
                                         self.update_table()))

        basic_x = 342
        Label(self, text='Total:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.total_count = Label(self, font=(MS_JH, 12))
        self.total_count.place(x=basic_x + 44, y=2)

        basic_x += 83
        Label(self, text='SSR:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.ssr_count = Label(self, font=(MS_JH, 10))
        self.ssr_count.place(x=basic_x + 34, y=-3)
        self.ssr_ratio = Label(self, font=(MS_JH, 9))
        self.ssr_ratio.place(x=basic_x + 44, y=13)

        basic_x += 80
        Label(self, text='SR:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.sr_count = Label(self, font=(MS_JH, 10))
        self.sr_count.place(x=basic_x + 25, y=-3)
        self.sr_ratio = Label(self, font=(MS_JH, 9))
        self.sr_ratio.place(x=basic_x + 35, y=13)

        basic_x += 78
        Label(self, text='R:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.r_count = Label(self, font=(MS_JH, 10))
        self.r_count.place(x=basic_x + 16, y=-3)
        self.r_ratio = Label(self, font=(MS_JH, 9))
        self.r_ratio.place(x=basic_x + 26, y=13)

        # 清空進行篩選的條件
        button = Button(self, text="清空條件", width=7, font=(MS_JH, 11))
        button.place(x=658, y=-1)
        button["command"] = self.clearing_filter
Пример #10
0
class DrawLotsFrame(MainFrameWithTable):
    def __init__(self, master, **kwargs):
        MainFrameWithTable.__init__(self, master, **kwargs)
        self.set_table_place(34, 29)
        self.table_model = TableModelAdvance()
        self.table_model.set_columns(RecordOfDrawLots.TABLE_VIEW_COLUMNS)
        # 滑鼠中鍵事件註冊,設定為更改角色詳細資訊,並選取該列
        self.table_view.bind("<Button-2>", lambda event: self.opening_character_update_window(event))
        self.table_view.setModel(self.table_model)

        self.filter_manager = FilterRuleManager()
        self.records = DrawLotsModel.select_record_list()
        self.events = DrawLotsModel.select_event_list()

        self._init_adding_frame()
        self._init_filter_frame()

        self.table.tkraise()  # 放上層,避免被其他元件遮到
        self.update_table()

    def _init_adding_frame(self):
        # 新增酒廠的按鈕
        button = Button(self, text="新增酒廠", width=2, height=5, wraplength=1, font=(MS_JH, 11))
        button.place(x=7, y=41)
        button["command"] = lambda: open_adding_event_window(self, lambda event: (
            self.events.insert(0, event), self.event_filter.set_objects(self.events)))

        # 新增記錄的按鈕
        button = Button(self, text="新增記錄", width=2, height=12, wraplength=1, font=(MS_JH, 12))
        button.place(x=5, y=155)
        button['command'] = self.adding_record
        button.bind('<Button-3>', lambda event: self.adding_record(limitation=False))

    def _init_filter_frame(self):
        basic_x = 20
        Label(self, text='E:', font=(MS_JH, 12)).place(x=basic_x, y=3)
        self.event_filter = FilteredObjectCombobox(
            self, setter=lambda obj: obj.name, getter=lambda obj: obj.e_id, width=16, justify=CENTER)
        self.event_filter.set_objects(self.events)
        self.event_filter.place(x=basic_x + 18, y=3)
        self.event_filter.bind('<<ComboboxSelected>>',
                               lambda x: (self.filter_manager.set_specific_condition(
                                   'event_id', self.event_filter.get()), self.update_table()), add='+')
        self.event_filter.bind('<Button-2>', lambda event: (open_updating_event_window(
            self, self.event_filter.selected_object, lambda: self.event_filter.set_objects(self.events))))

        basic_x += 158
        Label(self, text='C:', font=(MS_JH, 12)).place(x=basic_x, y=3)
        self.cost_filter = FilteredCombobox(self, width=6, justify=CENTER)
        self.cost_filter['values'] = DRAW_LOTS_COST
        self.cost_filter.place(x=basic_x + 20, y=3)
        self.cost_filter.bind('<<ComboboxSelected>>',
                              lambda x: (self.filter_manager.set_specific_condition('cost', self.cost_filter.get()),
                                         self.update_table()))

        basic_x += 90
        Label(self, text='R:', font=(MS_JH, 12)).place(x=basic_x, y=3)
        self.rank_filter = IntFilteredCombobox(self, width=3, justify=CENTER)
        self.rank_filter['values'] = [5, 4, 3]
        self.rank_filter.place(x=basic_x + 20, y=3)
        self.rank_filter.bind('<<ComboboxSelected>>',
                              lambda x: (self.filter_manager.set_specific_condition('rank', self.rank_filter.get()),
                                         self.update_table()))

        basic_x = 342
        Label(self, text='Total:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.total_count = Label(self, font=(MS_JH, 12))
        self.total_count.place(x=basic_x + 44, y=2)

        basic_x += 83
        Label(self, text='SSR:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.ssr_count = Label(self, font=(MS_JH, 10))
        self.ssr_count.place(x=basic_x + 34, y=-3)
        self.ssr_ratio = Label(self, font=(MS_JH, 9))
        self.ssr_ratio.place(x=basic_x + 44, y=13)

        basic_x += 80
        Label(self, text='SR:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.sr_count = Label(self, font=(MS_JH, 10))
        self.sr_count.place(x=basic_x + 25, y=-3)
        self.sr_ratio = Label(self, font=(MS_JH, 9))
        self.sr_ratio.place(x=basic_x + 35, y=13)

        basic_x += 78
        Label(self, text='R:', font=(MS_JH, 12)).place(x=basic_x, y=2)
        self.r_count = Label(self, font=(MS_JH, 10))
        self.r_count.place(x=basic_x + 16, y=-3)
        self.r_ratio = Label(self, font=(MS_JH, 9))
        self.r_ratio.place(x=basic_x + 26, y=13)

        # 清空進行篩選的條件
        button = Button(self, text="清空條件", width=7, font=(MS_JH, 11))
        button.place(x=658, y=-1)
        button["command"] = self.clearing_filter

    def update_table(self):
        results = self.filter_manager.filter(self.records)
        self.table_model.set_rows([result.get_table_view_info() for result in results])
        self.table_model.setSortOrder(columnName='Order', reverse=1)
        self.redisplay_table()
        self.table_view.resizeColumn(0, 55)  # DrawOrder
        self.table_view.resizeColumn(1, 178)  # Event
        self.table_view.resizeColumn(4, 120)  # Character

        # 就篩選結果更新統計資料
        self._update_statistic_by_specific_results(results)

    def _update_statistic_by_specific_results(self, results):
        # doing statistic: total, ssr, sr, r
        statistic = [0, 0, 0, 0]
        for record in results:
            record.take_statistic(statistic)

        # 特殊情況,顯示為 0 並結束
        if statistic[0] == 0:
            self.total_count["text"] = 0
            self.ssr_count["text"] = 0
            self.ssr_ratio["text"] = 0
            self.sr_count["text"] = 0
            self.sr_ratio["text"] = 0
            self.r_count["text"] = 0
            self.r_ratio["text"] = 0
            return

        self.total_count["text"] = '%3d' % statistic[0]
        self.ssr_count["text"] = statistic[1]
        self.ssr_ratio["text"] = self.convert_to_ratio(statistic[0], statistic[1])
        self.sr_count["text"] = statistic[2]
        self.sr_ratio["text"] = self.convert_to_ratio(statistic[0], statistic[2])
        self.r_count["text"] = statistic[3]
        self.r_ratio["text"] = self.convert_to_ratio(statistic[0], statistic[3])

    @staticmethod
    def convert_to_ratio(total, numerator):
        ratio = round(100.0 * numerator / total, 1)
        return str(ratio) + '%'

    def clearing_filter(self):
        self.event_filter.set(None)
        self.cost_filter.set('')
        self.rank_filter.set('')
        self.filter_manager.clean_specific_condition()
        self.update_table()

    def adding_record(self, limitation=True):
        open_adding_new_record_window(self, DrawLotsModel.get_suitable_events(self.events, limitation), lambda record: (
            self.records.append(record), self.update_table()))

    def do_double_clicking(self, event):
        record = self.get_record_by_order(self.table_model.getCellRecord(self.table_view.get_row_clicked(event), 0))
        open_updating_record_window(self, record, self.events, callback=self.update_table)

    def do_dragging_along_right(self, row_number):
        record = self.get_record_by_order(self.table_model.getCellRecord(row_number, 0))
        delete_record_with_conforming(
            self, record, lambda: (self.records.remove(record), self.update_table()))  # 直接從 list 中拿掉,不用重撈)

    def get_record_by_order(self, order):
        for each_record in self.records:
            if each_record.order == order:
                return each_record

    # 更改角色資訊
    def opening_character_update_window(self, event):
        self.table_view.handle_left_click(event)
        character = self.get_record_by_order(
            self.table_model.getCellRecord(self.table_view.get_row_clicked(event), 0)).character
        open_updating_character_window(self, character, lambda: None)
Пример #11
0
class CharacterFrame(MainFrameWithTable):
    def __init__(self, master, **kwargs):
        MainFrameWithTable.__init__(self, master, **kwargs)
        self.model = CharacterModel.CharacterFrameModel()
        self.set_table_place(34, 38)
        self.table_model = TableModelAdvance()
        self.table_model.set_columns(Character.TABLE_VIEW_COLUMNS, main_column="Nickname")
        self.table_view.setModel(self.table_model)

        self._init_upper_frame()
        self._init_left_frame()

        self.model.update_data()
        self.update_table()

    def _init_left_frame(self):
        self.character_count = IntVar()
        Label(self, textvariable=self.character_count, width=3, font=(SCP, 9, "bold")).place(x=5, y=10)

        # 新增記錄的按鈕,分別是日、台服
        button = Button(self, text="新增日服角色", width=2, height=10, wraplength=1, font=(MS_JH, 12))
        button.place(x=4, y=50)
        button["command"] = lambda: open_adding_new_jp_character_window(
            self, lambda character: self.callback_after_adding_character(character)
        )
        button = Button(self, text="台服角色", width=2, height=6, wraplength=1, font=(MS_JH, 11))
        button.place(x=5, y=280)
        button["command"] = lambda: open_adding_new_cn_character_window(
            self, lambda character: self.callback_after_adding_character(character)
        )

    def _init_upper_frame(self):
        filter_frame = Frame(self, width=self["width"], height=40)
        filter_frame.place(x=0, y=0)

        current_x = 45
        self.profession_selector = ProfessionSelector(filter_frame, self.updating_profession)
        self.profession_selector.place(x=current_x, y=-4)

        current_x += 199
        self.rank_selector = RankSelector(filter_frame, self.updating_rank)
        self.rank_selector.place(x=current_x, y=-4)

        # 所屬篩選
        current_x = 448
        Label(filter_frame, text="所屬:", font=(MS_JH, 10)).place(x=current_x + 10, y=-3)
        self.belonged = FilteredCombobox(filter_frame, width=6, justify=CENTER)
        self.belonged["values"] = BELONGEDS
        self.belonged.place(x=current_x, y=16)
        self.belonged.bind("<<ComboboxSelected>>", lambda event: self.updating_belonged())

        # 角色部分名稱篩選
        current_x += 75
        Label(filter_frame, text="篩選:", font=(MS_JH, 12)).place(x=current_x, y=7)
        self.request = StringVar()
        entry = Entry(filter_frame, width=9, textvariable=self.request, font=(MS_JH, 11))
        entry.place(x=current_x + 42, y=9)
        entry.bind("<Return>", lambda event: self.update_table())

        # 清空進行篩選的條件
        button = Button(filter_frame, text="清空條件", width=7, font=(MS_JH, 11))
        button.place(x=667, y=3)
        button["command"] = self.clearing_filters

    def update_table(self):
        # 將符合篩選條件的角色加入欲呈現表格中
        results = self.model.get_displaying_data(self.request.get())
        self.character_count.set(len(results))
        self.table_model.set_rows(results)

        self.table_model.setSortOrder(columnName="Rank", reverse=1)
        self.table_model.setSortOrder(columnName="Profession")

        self.redisplay_table()
        self.table_view.hide_column("ID")

    def callback_after_adding_character(self, character):
        self.model.append(character)
        self.update_table()

    def updating_profession(self, request):
        self.model.set_specific_condition("profession", request)
        self.update_table()

    def updating_rank(self, request):
        self.model.set_specific_condition("rank", request, match_requested_rank)
        self.update_table()

    def updating_belonged(self):
        self.model.set_specific_condition("belonged", self.belonged.get())
        self.update_table()

    def clearing_filters(self):
        self.profession_selector.clean_current_selection()
        self.rank_selector.clean_current_selection()
        self.belonged.set("")
        self.model.clean_specific_condition()
        self.request.set("")
        self.update_table()

    def do_double_clicking(self, event):
        character = self.get_corresponding_character_in_row(self.table_view.get_row_clicked(event))
        open_updating_character_window(self, character, lambda: self.update_table())

    # 主要供方便刪除測試或誤加的角色用,未檢查其他 table 中使用到的該角色
    def do_dragging_along_right(self, row_number):
        character = self.get_corresponding_character_in_row(row_number)
        delete_character_with_conforming(
            self, character, lambda: (self.model.remove(character), self.update_table())
        )  # 直接從 list 中拿掉,不用重撈

    def get_corresponding_character_in_row(self, row_number):
        selected_id = self.table_model.getCellRecord(row_number, 0)
        return self.model.get_specific_datum("c_id", selected_id)
Пример #12
0
class CharacterFrame(MainFrameWithTable):
    def __init__(self, master, **kwargs):
        MainFrameWithTable.__init__(self, master, **kwargs)
        self.model = CharacterModel.CharacterFrameModel()
        self.set_table_place(34, 38)
        self.table_model = TableModelAdvance()
        self.table_model.set_columns(Character.TABLE_VIEW_COLUMNS,
                                     main_column='Nickname')
        self.table_view.setModel(self.table_model)

        self._init_upper_frame()
        self._init_left_frame()

        self.model.update_data()
        self.update_table()

    def _init_left_frame(self):
        self.character_count = IntVar()
        Label(self,
              textvariable=self.character_count,
              width=3,
              font=(SCP, 9, 'bold')).place(x=5, y=10)

        # 新增記錄的按鈕,分別是日、台服
        button = Button(self,
                        text="新增日服角色",
                        width=2,
                        height=10,
                        wraplength=1,
                        font=(MS_JH, 12))
        button.place(x=4, y=50)
        button["command"] = lambda: open_adding_new_jp_character_window(
            self, lambda character: self.callback_after_adding_character(
                character))
        button = Button(self,
                        text="台服角色",
                        width=2,
                        height=6,
                        wraplength=1,
                        font=(MS_JH, 11))
        button.place(x=5, y=280)
        button["command"] = lambda: open_adding_new_cn_character_window(
            self, lambda character: self.callback_after_adding_character(
                character))

    def _init_upper_frame(self):
        filter_frame = Frame(self, width=self['width'], height=40)
        filter_frame.place(x=0, y=0)

        current_x = 45
        self.profession_selector = ProfessionSelector(filter_frame,
                                                      self.updating_profession)
        self.profession_selector.place(x=current_x, y=-4)

        current_x += 199
        self.rank_selector = RankSelector(filter_frame, self.updating_rank)
        self.rank_selector.place(x=current_x, y=-4)

        # 所屬篩選
        current_x = 448
        Label(filter_frame, text='所屬:',
              font=(MS_JH, 10)).place(x=current_x + 10, y=-3)
        self.belonged = FilteredCombobox(filter_frame, width=6, justify=CENTER)
        self.belonged['values'] = BELONGEDS
        self.belonged.place(x=current_x, y=16)
        self.belonged.bind('<<ComboboxSelected>>',
                           lambda event: self.updating_belonged())

        # 角色部分名稱篩選
        current_x += 75
        Label(filter_frame, text='篩選:', font=(MS_JH, 12)).place(x=current_x,
                                                                y=7)
        self.request = StringVar()
        entry = Entry(filter_frame,
                      width=9,
                      textvariable=self.request,
                      font=(MS_JH, 11))
        entry.place(x=current_x + 42, y=9)
        entry.bind('<Return>', lambda event: self.update_table())

        # 清空進行篩選的條件
        button = Button(filter_frame, text="清空條件", width=7, font=(MS_JH, 11))
        button.place(x=667, y=3)
        button["command"] = self.clearing_filters

    def update_table(self):
        # 將符合篩選條件的角色加入欲呈現表格中
        results = self.model.get_displaying_data(self.request.get())
        self.character_count.set(len(results))
        self.table_model.set_rows(results)

        self.table_model.setSortOrder(columnName='Rank', reverse=1)
        self.table_model.setSortOrder(columnName='Profession')

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

    def callback_after_adding_character(self, character):
        self.model.append(character)
        self.update_table()

    def updating_profession(self, request):
        self.model.set_specific_condition('profession', request)
        self.update_table()

    def updating_rank(self, request):
        self.model.set_specific_condition('rank', request,
                                          match_requested_rank)
        self.update_table()

    def updating_belonged(self):
        self.model.set_specific_condition('belonged', self.belonged.get())
        self.update_table()

    def clearing_filters(self):
        self.profession_selector.clean_current_selection()
        self.rank_selector.clean_current_selection()
        self.belonged.set('')
        self.model.clean_specific_condition()
        self.request.set('')
        self.update_table()

    def do_double_clicking(self, event):
        character = self.get_corresponding_character_in_row(
            self.table_view.get_row_clicked(event))
        open_updating_character_window(self, character,
                                       lambda: self.update_table())

    # 主要供方便刪除測試或誤加的角色用,未檢查其他 table 中使用到的該角色
    def do_dragging_along_right(self, row_number):
        character = self.get_corresponding_character_in_row(row_number)
        delete_character_with_conforming(
            self, character, lambda: (self.model.remove(
                character), self.update_table()))  # 直接從 list 中拿掉,不用重撈

    def get_corresponding_character_in_row(self, row_number):
        selected_id = self.table_model.getCellRecord(row_number, 0)
        return self.model.get_specific_datum('c_id', selected_id)
Пример #13
0
class CharacterSelectionWindow(BasicWindow):
    def __init__(self, master, callback, character_selected, width=422, height=155, **kwargs):
        BasicWindow.__init__(self, master, width=width, height=height, **kwargs)
        self.title('Character selection')

        self.records = None
        self.update_records()
        self.filter_manager = FilterRuleManager()
        self.filter_manager.set_comparison_rule(0)
        self.filter_manager.set_comparison_rule(1)

        self._init_widgets()
        self._init_character_selected(character_selected)
        self.callback = callback

    def _init_widgets(self):
        self.profession_selector = ProfessionSelector(self, self.updating_request_profession)
        self.profession_selector.place(x=5, y=5)
        self.rank_selector = RankSelector(self, self.updating_request_rank)
        self.rank_selector.place(x=5, y=53)

        Label(self, text='所屬', width=5, font=("", 10)).place(x=221, y=5)
        self.belonged_selector = FilteredCombobox(self, width=7, font=("", 11), justify=CENTER)
        self.belonged_selector['values'] = BELONGEDS
        self.belonged_selector.place(x=213, y=22)
        self.belonged_selector.bind('<<ComboboxSelected>>',
                                    lambda x: self.updating_request_belonged(self.belonged_selector.get()))
        self.belonged_selector.bind('<Return>', lambda x: self.character_selector.focus_set())

        Label(self, text='篩選', width=5, font=("", 11)).place(x=222, y=54)
        self.name_request = StringVar(value='')
        entry = Entry(self, width=8, textvariable=self.name_request, font=("", 12))
        entry.place(x=214, y=73)
        entry.bind('<Return>', lambda x: self.updating_request_name())
        entry.bind('<Escape>', lambda x: (self.name_request.set(''), self.updating_request_name()))

        Label(self, text='Character', width=10, font=("", 12)).place(x=304, y=26)
        self.character_selector = ttk.Combobox(self, state='readonly', width=10, font=("", 12), justify=CENTER)
        self.character_selector.place(x=305, y=48)
        self.character_selector.bind('<Return>', lambda x: self.submitting())

        # 熱鍵,直接指過來
        self.bind('<f>', lambda x: self.character_selector.focus_set())

        y_position = 115
        # 送交的按鈕
        button = Button(self, text="選擇此角色", width=25, borderwidth=3)
        button.place(x=17, y=y_position)
        button["command"] = self.submitting

        # 新增角色的按鈕
        button = Button(self, text="新增角色", width=9, borderwidth=3)
        button.place(x=225, y=y_position)
        button["command"] = lambda: open_adding_new_jp_character_window(
            self, lambda new_character: (self.update_records(), self.updating_character_selector()))

        # 取消並結束的按鈕
        button = Button(self, text="放棄選擇", width=9, borderwidth=3)
        button.place(x=317, y=y_position)
        button["command"] = self.destroy

    def _init_character_selected(self, character_selected):
        if character_selected is None:
            pass
        elif isinstance(character_selected, Character):
            self.profession_selector.select(character_selected.profession)
            self.rank_selector.select(character_selected.rank)
            self.updating_character_selector()
            self.character_selector.set(character_selected.nickname)
        else:
            raise TypeError('In CharacterSelectionWindow, arg: \"character_selected\"')

    def updating_request_profession(self, profession):
        self.filter_manager.set_specific_condition(2, profession)
        self.updating_character_selector()
        self.character_selector.focus_set()

    def updating_request_rank(self, rank):
        self.filter_manager.set_specific_condition(3, rank, match_requested_rank)
        self.updating_character_selector()
        self.character_selector.focus_set()

    def updating_request_belonged(self, belonged):
        self.filter_manager.set_specific_condition(4, belonged)
        self.updating_character_selector()

    def updating_request_name(self):
        self.updating_character_selector()
        self.character_selector.focus_set()

    # 清除原本的選擇,並更新可選擇的角色
    def updating_character_selector(self):
        self.character_selector.set('')
        character_matched = []
        for character_infos in self.filter_manager.filter(self.records, self.name_request.get()):
            character_matched.append(character_infos[0])
        self.character_selector['values'] = character_matched

    # 有選擇的情況下才回傳,否則彈出錯誤視窗
    def submitting(self):
        if self.character_selector.get() != '':
            self.callback(CharacterModel.select_character_by_specific_column('Nickname', self.character_selector.get()))
            self.destroy()
        else:
            tkMessageBox.showwarning("Character haven't selected", '\"Character\" 未選\n', parent=self)

    def update_records(self):
        self.records = CharacterModel.select_character_info_for_character_selector()
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