class TrialsPlotWindow(BaseWidget): """ Show all boxes live state for an experiment""" EVENTS_TO_SHOW = [StateOccurrence, EventOccurrence] def __init__(self, session): """ :param session: session reference :type session: pycontrolgui.windows.detail.entities.session_window.SessionWindow """ BaseWidget.__init__(self, session.name) self.session = session self._refreshbtn = ControlButton('Refresh Timeline') self._list = ControlCheckBoxList('Events to show') self._events = ControlEventsGraph(session.name) self._list.hide() self._events.add_popup_menu_option('Show / Hide Events', self.__toggle_events_to_show_evt) self._events.add_track('') # for state_id, state_name in sorted(self.session.setup.board_task.states.items(), key=lambda x: x[0]): # self._events.add_track(state_name) self._history_index = 0 self._last_event = None self._session_start_timestamp = datetime_now.now() self.formset = ['_refreshbtn', '_list', '=', '_events'] self._list_of_states_colors = [ '#E0E0E0', '#FFCC99', '#FFFF99', 'CCFF99', '#99FFFF', '#99CCFF', '#FF99CC' ] self._states_names = {} self._timer = QTimer() self._timer.timeout.connect(self.read_message_queue) self._refreshbtn.value = self.__refresh_evt self._list.value = [(evt_type.__name__, True) for evt_type in self.EVENTS_TO_SHOW] self._list.changed_event = self.__list_changed_evt self._available_events = dict([(evt_type.__name__, evt_type) for evt_type in self.EVENTS_TO_SHOW]) self.__list_changed_evt() def __refresh_evt(self): """Clears the entire timeline and re-draws all the checked events from T = 0 """ self._events.clear() self._history_index = 0 self.read_message_queue() def __list_changed_evt(self): self._events_2_draw = tuple([ self._available_events[event_name] for event_name in self._list.value ] + [SessionInfo]) def __toggle_events_to_show_evt(self): if self._list.visible: self._list.hide() else: self._list.show() def show(self): # Prevent the call to be recursive because of the mdi_area if hasattr(self, '_show_called'): BaseWidget.show(self) return self._show_called = True self.mainwindow.mdi_area += self del self._show_called self._stop = False # flag used to close the gui in the middle of a loading self.read_message_queue() if not self._stop: self._timer.start(conf.TIMELINE_PLUGIN_REFRESH_RATE) def hide(self): self._timer.stop() self._stop = True def before_close_event(self): self._timer.stop() self._stop = True self.session.trialsplot_action.setEnabled(True) def __add_event(self, start_timestamp, end_timestamp, track_id, name): self._last_event = self._events.add_event( start_timestamp, end_timestamp, track=track_id, title=name, color=self._list_of_states_colors[track_id % len( self._list_of_states_colors)]) self._events.value = start_timestamp def timediff_ms(self, time_f, time_i): diff = datetime_now.now() diff = time_f - time_i elapsed_ms = (diff.days * 86400000) + \ (diff.seconds * 1000) + (diff.microseconds / 1000) return elapsed_ms def read_message_queue(self): """ Update board queue and retrieve most recent messages """ try: recent_history = self.session.messages_history[self. _history_index:] for message in recent_history: if self._stop: return if not isinstance(message, self._events_2_draw): continue if isinstance(message, StateOccurrence): if message.state_name not in self._states_names.keys(): self._states_names[message.state_name] = len( self._states_names) if not (math.isnan(message.start_timestamp) or math.isnan(message.end_timestamp)): bpod_start = int(round(message.start_timestamp * 1000)) bpod_end = int(round(message.end_timestamp * 1000)) self.__add_event( bpod_start, bpod_end, self._states_names[message.state_name], message.state_name) elif isinstance(message, SessionInfo): if message.content == 'SESSION-STARTED': self._session_start_timestamp = message.pc_timestamp elif isinstance(message, EventOccurrence): ts = None # in case we don't find any valid timestamp, don't add the event to the timeline # check which timestamp will be used. host timestamp wins over pc timestamp if message.pc_timestamp is not None: ts = self.timediff_ms(message.pc_timestamp, self._session_start_timestamp) # proceed if we have a valid timestamp if ts is not None: # create a new event slot in the timeline in case current message is entirely new if message.event_name not in self._states_names.keys(): self._states_names[message.event_name] = len( self._states_names) # add a time delta to ts so the event can be shown in the timeline self.__add_event( ts - 10, ts + 10, self._states_names[message.event_name], message.event_name) self._history_index += 1 QEventLoop() except RunSetupError as err: logger.error(str(err), exc_info=True) self._timer.stop() @property def mainwindow(self): return self.session.mainwindow @property def title(self): return BaseWidget.title.fget(self) @title.setter def title(self, value): title = 'Trials-plot: {0}'.format(value) BaseWidget.title.fset(self, title)
class ExportWindow(BaseWidget): def __init__(self, parent=None): BaseWidget.__init__(self, 'Export data', parent_win=parent) self.set_margin(5) self.setMinimumHeight(600) self.setMinimumWidth(800) self._tree = ControlTree('Data') self._apply = ControlButton('Apply', checkable=True) self._progress = ControlProgress('Progress') self._add = ControlButton('Add') self._remove = ControlButton('Remove') self._export_list = ControlList('Columns to export') self._outdir = ControlDir('Output directory') self._outfile = ControlText('Output file name') self._toggleevts = ControlCheckBox('Split files by events') self._splitevents = ControlCheckBoxList('Events') self._evtsreload = ControlButton('Reload events') self._formset = [[['_add', '_tree'], '||', ['_remove', '_export_list']], '_toggleevts', '_evtsreload', '_splitevents', '_outdir', '_outfile', '_apply', '_progress'] self._add.value = self.__add_column_event self._remove.value = self.__remove_column_event self._apply.value = self.__apply_btn_event self._evtsreload.value = self.__reload_events self._outdir.changed_event = self.__update_outfile_name_event self._outfile.changed_event = self.__update_outfile_name_event self._toggleevts.changed_event = self.__toggleevents_visibility self._splitevents.changed_event = self.__update_outfile_name_event self._splitevents.selection_changed_event = self.__update_outfile_name_event self._tree.show_header = False self._apply.icon = conf.ANNOTATOR_ICON_MOTION self._evtsreload.icon = conf.ANNOTATOR_ICON_REFRESH self._add.icon = conf.ANNOTATOR_ICON_ADD self._remove.icon = conf.ANNOTATOR_ICON_REMOVE self._progress.hide() self._splitevents.hide() self._evtsreload.hide() self._apply.enabled = False self._properties = [] ########################################################################### ### EVENTS ################################################################ ########################################################################### def __toggleevents_visibility(self): if self._toggleevts.value: self._splitevents.show() self._evtsreload.show() else: self._splitevents.hide() self._evtsreload.hide() def __field_full_name(self, tree_item): name = tree_item.text(0) while True: tree_item = tree_item.parent() if tree_item is None: break name = "{0} > {1}".format(tree_item.text(0), name) return name def __add_column_event(self): self.__update_outfile_name_event() item = self._tree.selected_item if item is None: return if hasattr(item, 'data_function'): self._export_list += [self.__field_full_name(item)] self._properties.append((len(item.win), item.data_function)) elif isinstance(item.win, Value): self._export_list += [self.__field_full_name(item)] self._properties.append((len(item.win), item.win.get_value)) def __remove_column_event(self): self.__update_outfile_name_event() if self._export_list.selected_row_index is None: return elif self._export_list.selected_row_index >= 0: self._properties.pop(self._export_list.selected_row_index) self._export_list -= -1 def __update_outfile_name_event(self): """ Update the output filename """ filename = self._outfile.value if len(filename.strip()) == 0: return outfilepath, outfile_extension = os.path.splitext(filename) names = [outfilepath] if len(outfilepath) > 0 else [] if len(list(self._splitevents.value)) > 0: if '{event}' not in outfilepath: names.append('{event}') if '{start}' not in outfilepath: names.append('{start}') if '{end}' not in outfilepath: names.append('{end}') self._outfile.value = ('-'.join(names) + '.csv') self._apply.enabled = True def __apply_btn_event(self): if self._apply.checked: if len(self._properties) == 0: QMessageBox.about( self, "Error", "You need to select at least one value to export.") self._apply.checked = False return if self._outfile.value is None or len( self._outfile.value.strip()) == 0: QMessageBox.about( self, "Error", "You need to select the name of the output file.") self._apply.checked = False return if self._outdir.value is None or len(self._outdir.value) == 0: QMessageBox.about( self, "Error", "You need to select the name of the output directory.") self._apply.checked = False return self.__update_outfile_name_event() self._export_list.enabled = False self._tree.enabled = False self._add.enabled = False self._remove.enabled = False self._outdir.enabled = False self._outfile.enabled = False self._apply.label = 'Cancel' ### calculate the video cuts ############################# timeline = self.parent().timeline selected_events = self._splitevents.value videocuts = [] if len(selected_events): # use the events to cut the video totalframes = 0 for row in timeline.rows: for event in row.events: if event.title not in selected_events: continue b = event.begin e = event.end totalframes += e - b videocuts.append((int(b), int(e), event.title)) videocuts = sorted(videocuts, key=lambda x: x[0]) else: # no events were selected end = max([size for size, func in self._properties]) totalframes = end videocuts = [(0, int(end), None)] ########################################################## self._progress.min = 0 self._progress.max = totalframes self._progress.show() for b, e, eventname in videocuts: filename = self._outfile.value filename = filename.format(event=eventname, start=b, end=e) filename = os.path.join(self._outdir.value, filename) with open(filename, 'w') as out: ## write the csv columns headers out.write('frame;') for values in self._export_list.value: out.write(('{0};'.format(values[0]))) out.write('\n') ## write the values for index in range(b, e): out.write('{0};'.format(index)) for _, func in self._properties: out.write('{0};'.format(func(index))) out.write('\n') self._progress += 1 self._export_list.enabled = True self._tree.enabled = True self._add.enabled = True self._remove.enabled = True self._outdir.enabled = True self._outfile.enabled = True self._apply.label = 'Apply' self._apply.checked = False self._progress.hide() def __copy_tree_node(self, item, new_item): new_item.win = item.win if hasattr(item, 'data_function'): new_item.data_function = item.data_function def __reload_events(self): """ Find all the events available on the timeline """ timeline = self.parent().timeline rows = timeline.rows events = {} for row in rows: for event in row.events: events[event.title] = True events = sorted(events.keys()) loaded_events = dict(self._splitevents.items) self._splitevents.value = [(e, loaded_events.get(e, False)) for e in events] @property def project(self): return self._project @project.setter def project(self, value): self._project = value self._tree.clear() self._tree.clone_tree(value.tree, copy_function=self.__copy_tree_node) self.__reload_events()
class SceneApp(HeatMapApp): def __init__(self, title=''): self._points_values = None #used to map a color for each tracking point super(SceneApp, self).__init__(title) ##### CONTROLS ############################################################################## self._scene_file = ControlFile('Scene') self._scene_toggle_objs_list = ControlButton('Show/Hide objects', checkable=True) self._scene_objs_list = ControlCheckBoxList('Objects') self._scene_opengl = ControlOpenGL('OpengGL Scene') self._scene_points_alfa = ControlSlider('Transparency', 10, 0, 100) self._scene_bg_color = ControlCombo('Background color') self._scene_apply_colorBnds = ControlButton('Apply colors boundaries') self._scene_points_size = ControlCombo('Points size') self._scene_obj_color = ControlText('Object color') ############################################################################################# self._modules_tabs.update({ 'Heat map': [('_heatmapColor', ' | ', 'Filters:', '_toggleHeatmapVars', '_toggleSphereVisibility', '_sphere', ' | ', '_apply2Heatmap', ' '), ('_heatmapVarsList', '_heatmapVars', '_heatmapHigherVarsValues', '_heatMapMinVar', '_heatmapVarsBnds', '_heatMapMaxVar'), ({ '1:Map': ['_heatmap'], '0:Scene': [[('_scene_file', ' ', '_scene_toggle_objs_list', ' ', '_scene_bg_color', ' | ', '_scene_points_size', ' | ', '_scene_apply_colorBnds'), '_scene_points_alfa', '_scene_obj_color', '_scene_objs_list'], '=', '_scene_opengl'] }, '_heatmapColorsBnds')] }) ############################################################################################# self._scene_bg_color += ('White', '1,1,1,1.0') self._scene_bg_color += ('Gray', '0.3,0.3,0.3,1.0') self._scene_bg_color += ('Black', 'None') self._scene_points_size += '1' self._scene_points_size += '3' self._scene_points_size += '6' self._scene_points_size += '8' self._scene_objs_list.hide() self._scene_obj_color.hide() self._scene_objs_list.changed = self.__changed_objects_list_event self._scene_toggle_objs_list.value = self.__toggle_objects_list_event self._scene_points_alfa.changed = self.__changed_scene_points_alfa_event self._scene_bg_color.changed = self.__changed_background_color_event self._scene_apply_colorBnds.value = self.__scene_apply_color_bnds_event self._scene_points_size.changed = self.__changed_scene_points_size_event self._scene_objs_list.selectionChanged = self.__selectionchanged_object_list_event self._scene_obj_color.changed = self.__changed_object_color_event self._scene = None self._scene_file.changed = self.__scene_file_selected self._scene_opengl.clear_color = 1, 1, 1, 1 #self._scene_file.value = '/home/ricardo/Desktop/01Apollo201403210900/01Apollo201403210900_Scenario.obj' def initForm(self): super(SceneApp, self).initForm() #self._splitters[0].setStretchFactor(0,10) #self._splitters[0].setStretchFactor(1,90) ############################################################################################ ### EVENTS ################################################################################# ############################################################################################ def __changed_object_color_event(self): index = self._scene_objs_list.mouseSelectedRowIndex self._scene.objects[index].color = eval(self._scene_obj_color.value) self._scene_opengl.repaint() def __selectionchanged_object_list_event(self): index = self._scene_objs_list.mouseSelectedRowIndex self._scene_obj_color.value = str(self._scene.objects[index].color) self._scene_obj_color.label = 'Object color ({0})'.format( self._scene.objects[index].name) def __changed_scene_points_size_event(self): self._scene.points_size = eval(self._scene_points_size.value) self._scene_opengl.repaint() def __toggle_objects_list_event(self): if self._scene_toggle_objs_list.checked: self._scene_objs_list.show() self._scene_obj_color.show() else: self._scene_objs_list.hide() self._scene_obj_color.hide() def __changed_background_color_event(self): self._scene_opengl.clear_color = eval(self._scene_bg_color.value) def __changed_scene_points_alfa_event(self): if self._points_values != None: self._scene.colors = self.__gen_colors(self._points_values.copy()) self._scene_opengl.repaint() def __changed_objects_list_event(self): x, y, z = 0.0, 0.0, 0.0 count = 0.0 for obj in self._scene.objects: obj.active = obj.name in self._scene_objs_list.value obj.draw_faces = True if obj.active: for point in obj.points: x += point[0] y += point[1] z += point[2] count += 1.0 if count == 0.0: count = 1.0 self._scene._center = x / count, y / count, z / count self._scene_opengl.repaint() def __scene_file_selected(self): if len(self._scene_file.value) == 0: return self._scene = CustomScene() w = WavefrontOBJReader(self._scene_file.value) self._scene.objects = w.objects self._scene_opengl.value = self._scene self._scene_objs_list.clear() for obj in self._scene.objects: self._scene_objs_list += (obj.name, True) def __gen_colors(self, values): if len(values) == 0: return [] if self._heatmapColor.value == vv.CM_BONE: func = 'bone' if self._heatmapColor.value == vv.CM_COOL: func = 'cool' if self._heatmapColor.value == vv.CM_COPPER: func = 'copper' if self._heatmapColor.value == vv.CM_GRAY: func = 'gray' if self._heatmapColor.value == vv.CM_HOT: func = 'hot' if self._heatmapColor.value == vv.CM_HSV: func = 'hsv' if self._heatmapColor.value == vv.CM_PINK: func = 'pink' if self._heatmapColor.value == vv.CM_JET: func = 'jet' if self._heatmapColor.value == vv.CM_AUTUMN: func = 'autumn' if self._heatmapColor.value == vv.CM_SPRING: func = 'spring' if self._heatmapColor.value == vv.CM_SUMMER: func = 'summer' if self._heatmapColor.value == vv.CM_WINTER: func = 'winter' normalized_vals = np.float32(values) / np.float32(values).max() normalized_vals = normalized_vals - normalized_vals.min() maximum = normalized_vals.max() func = getattr(cm, func) colors = [] alpha = float(self._scene_points_alfa.value) / 100.0 for v in normalized_vals: color = func(v / maximum) colors.append((color[0], color[1], color[2], alpha)) return colors def __scene_apply_color_bnds_event(self): self._scene_apply_colorBnds.form.setStyleSheet("") if self._heatmapImg is None or not self._heatmapImg.any(): return lower, higher = self._heatmapColorsBnds.value a = self._points_values.copy() a[a < lower] = lower a[a > higher] = higher self._scene.colors = self.__gen_colors(a) def changed_heatmap_colors_bounds_event(self): super(SceneApp, self).changed_heatmap_colors_bounds_event() self._scene_apply_colorBnds.form.setStyleSheet("color: red") def changed_heatmap_color_event(self): super(SceneApp, self).changed_heatmap_color_event() if self._points_values != None: self._scene.colors = self.__gen_colors(self._points_values.copy()) self._scene_opengl.repaint() def calculate_heatmap_event(self): super(SceneApp, self).calculate_heatmap_event() if self._scene: #Filter for the data from a lower and upper frame self._progress.min = lower = 0 if self._boundings.value[ 0] < 0 else int(self._boundings.value[0]) self._progress.max = higher = len( self._data) if self._boundings.value[1] > ( len(self._data) + 1) else int(self._boundings.value[1]) #Calculate the size of the map x_diff = self._data.xRange[1] - self._data.xRange[0] y_diff = self._data.yRange[1] - self._data.yRange[0] z_diff = self._data.zRange[1] - self._data.zRange[0] scale = self.fit_scale(x_diff, y_diff, z_diff) #Fit the best scale value try: sphere = sphere_x, sphere_y, sphere_z, sphere_r = eval( self._sphere.value) except: sphere = None min_var, max_var = self._heatmapVarsBnds.value which_var = 0 if self._heatmapVarsList.value == 'Velocity' else 1 values = [] points = [] for i in range(lower, higher): if (i % 3000) == 0: self._progress.value = i if self._data[i] != None: x, y, z = position = self._data[i].position x += abs(self._data.xRange[0]) y += abs(self._data.yRange[0]) z += abs(self._data.zRange[0]) x = int(round(x * scale)) y = int(round(y * scale)) z = int(round(z * scale)) #Filter position by a defined sphere if sphere != None and lin_dist3d( (x, y, z), (sphere_x, sphere_y, sphere_z)) > sphere_r: continue #Use variables to construct the map, or positions if self._toggleHeatmapVars.checked: #velocities array has less 1 element than positions array if which_var == 0 and len(self._velocities) <= i: continue #accelarations array has less 2 element than positions array if which_var == 1 and len(self._accelerations) <= i: continue var = self._velocities[ i] if which_var == 0 else self._accelerations[i] #Filter by variable boundaries if not (min_var <= var <= max_var): continue values.append(self._heatmapImg[z, x, y]) points.append(position) self._progress.value = higher self._points_values = np.float32(values) self._scene.points = points self._scene.colors = self.__gen_colors(self._points_values.copy()) self._scene_apply_colorBnds.form.setStyleSheet("") self._scene_opengl.repaint()
class GraphApp(BaseApp): """Application form""" def __init__(self, title='Variables graphs'): super(GraphApp,self).__init__(title) self._graph = ControlVisVis("Graph") self._toggleVars = ControlButton('Show/Hide variables', checkable=True) self._loadGraph = ControlButton('Apply') self._varsList = ControlCheckBoxList('Variables') self._varsList += ('Frames',True) self._varsList += ('X',True) self._varsList += ('Y',True) self._varsList += ('Z',False) self._varsList += ('Velocity',False) self._varsList += ('Acceleration',False) self._modules_tabs.update({ 'Graphs': [ ('_toggleVars',' '), '_varsList', '_loadGraph', '_graph'], }) self._loadGraph.value = self.__calculate_graph self._toggleVars.value = self.__show_hide_variables self._varsList.hide() self._loadGraph.hide() def __show_hide_variables(self): #Show and hide the variables list if self._toggleVars.checked: self._varsList.show() self._loadGraph.show() else: self._varsList.hide() self._loadGraph.hide() def __calculate_graph(self): #Render the graph if self._data==None: self.warning("Please load the data first.", "The data is missing") return lower = 0 if self._boundings.value[0]<0 else self._boundings.value[0] higher = len(self._data) if self._boundings.value[1]>(len(self._data)+1) else self._boundings.value[1] self._progress.min = lower self._progress.max = higher values = [] variables = self._varsList.value if len(variables)>3: self.warning("Please select the maximum of 3 variables.", "Too many variables selected") return for i in range(int(lower), int(higher)-2 ): self._progress.value = i if self._data[i]!=None: val = [] pos = self._data[i].position if 'Frames' in variables: val.append(i) if 'X' in variables: val.append(pos[0]) if 'Y' in variables: val.append(pos[1]) if 'Z' in variables: val.append(pos[2]) if 'Velocity' in variables: val.append(self._velocities[i]) if 'Acceleration' in variables: val.append(self._accelerations[i]) values.append( val ) self._graph.value = [values]
class SimpleExample1(BaseWidget): def __init__(self): super(SimpleExample1, self).__init__(' Thực Tập Cơ Sở ') #main menu self.mainmenu = [{ 'File': [{ 'Open Excel': self.__open, 'icon': 'img/folder_open.png' }, '-', { 'Import': self.__import, 'icon': 'img/import_icon.png' }] }] #tkinler for messagebox root = tk.Tk() root.withdraw() #list self._list = ControlList('Danh sách') self._list.readonly = True #1.open file excel và heap sort self._file = ControlFile('Chọn file Excel') self._butheapsort = ControlButton('Heap Sort') self._butheapsort.icon = 'img/sort_icon.png' self._butheapsort.value = self.__heapsort self._butloadexcel = ControlButton('Load') self._butloadexcel.icon = 'img/load_icon.png' self._butloadexcel.value = self.__load self._butremoveloadexcel = ControlButton('Hủy bỏ') self._butremoveloadexcel.icon = 'img/remove_icon.png' self._butremoveloadexcel.value = self.__removeloadexcel #2.thêm thửa đất self._diachi = ControlText('Địa chỉ') self._dientich = ControlText('Diện tích') self._chusohuuhientai = ControlText('Chủ sở hữu hiện tại') self._loainha = ControlText('Loại nhà') self._mucdichsudung = ControlText('Mục đích Sử dụng') self._giatien = ControlText('Giá tiền') self._but1 = ControlButton('Thêm thửa đất') self._but1.value = self.__add self._but1.icon = 'img/add_icon.png' #3.tìm kiếm thử đất và xóa #tìm kiếm self._butsearch = ControlButton('Tìm kiếm') self._butsearch.icon = 'img/search_icon.png' self._butsearch.value = self.__search self._timkiem = ControlText('Tìm Kiếm') self._checklisttimkiem = ControlCheckBoxList('Chọn tiêu chí tìm kiếm:') self._checklisttimkiem.hide() self._buttonhideshowtimkiem = ControlButton('Hiển thị tiêu chí') self._buttonhideshowtimkiem.value = self._buthideshowtimkiem self._buttonhideshowtimkiem.icon = 'img/show.png' self._buthuybo = ControlButton('Hủy bỏ') self._buthuybo.icon = 'img/remove_icon.png' self._buthuybo.value = self._huybo #xóa self._textxoa = ControlText('Nhập nội dung cần xóa') self._butxoa = ControlButton('Xoá') self._butxoa.icon = 'img/delete_icon.png' self._butxoa.value = self.__xoa self._checklistxoa = ControlCheckBoxList('Chọn tiêu chí xóa:') self._checklistxoa.hide() self._buttonhideshowxoa = ControlButton('Hiển thị tiêu chí') self._buttonhideshowxoa.value = self._buthideshowxoa self._buttonhideshowxoa.icon = 'img/show.png' #4.xuất self._directory = ControlDir('Chọn chỗ xuất file excel') self._tenfilexuat = ControlText('Tên file xuất') self._butxuat = ControlButton('Xuất') self._butxuat.icon = 'img/export_icon.png' self._butxuat.value = self.__xuat #5.merge self._filemerge = ControlFile('Chọn file Excel cần merge') self._butimport = ControlButton('Import') self._butimport.icon = 'img/import2_icon.png' self._butimport.value = self._import self._butmerge = ControlButton('Gộp') self._butmerge.icon = 'img/merge_icon' self._butmerge.value = self._merge self._butmerge.hide() self._listmerge = ControlList('Danh sách import') self._listmerge.readonly = True self._buttonhideshow = ControlButton('Hiển thị tùy chọn') self._buttonhideshow.value = self._buthideshow self._buttonhideshow.hide() self._buttonhideshow.icon = 'img/show.png' self._checklist = ControlCheckBoxList( 'Chọn tiêu chí giữ trong danh sách import:') self._checklist.hide() self._buttonremovemerge = ControlButton('Hủy bỏ') self._buttonremovemerge.value = self._remove self._buttonremovemerge.icon = 'img/remove_icon.png' self._buttonremovemerge.hide() #formset as layout self.formset = [{ '1.Mở File và Heap Sort': [ ' ', '_file', ' ', (' ', '_butloadexcel', '_butremoveloadexcel', '_butheapsort', ' '), ' ' ], '2.Thêm': [ ' ', '_diachi', '_dientich', '_chusohuuhientai', '_loainha', '_mucdichsudung', '_giatien', ' ', (' ', '_but1', ' '), ' ' ], '3.Tìm kiếm và Xóa': [ ' ', '_textxoa', ' ', (' ', '_butxoa', '_buttonhideshowxoa', '_checklistxoa', ' '), ' ', '_timkiem', ' ', (' ', '_butsearch', '_buttonhideshowtimkiem', '_checklisttimkiem', '_buthuybo', ' '), ' ' ], '4.Xuất': [ ' ', '_directory', ' ', '_tenfilexuat', ' ', (' ', '_butxuat', ' '), ' ' ], '5.Merge danh sách': [ '_filemerge', (' ', '_butimport', '_butmerge', '_buttonremovemerge', '_buttonhideshow', '_checklist', ' '), '_listmerge' ], }, '', '', '_list'] #event for mainmenu def __open(self): self._file.click() def __import(self): self._filemerge.click() #event tab 1 #event for _butremoveloadexcel def __removeloadexcel(self): if not values: messagebox.showwarning("Warning", "Không có thông tin cần loại bỏ") else: values.clear() fsqc.clear() self._refresh() #event for _butheapsort def __heapsort(self): if self._list.rows_count <= 1: messagebox.showwarning("Warning", "không có list để sort") else: heap_sort() self._refresh() #event for load button def __load(self): if not self._file.value: tk.messagebox.showwarning("Warning", "Đường dẫn trống") else: try: if self._file.value != '': path = self._file.value read(path) self._list.value = [values_name] n = 0 for i in range(int(len(values) / numberofcols[0])): self._list.__add__(values[n:n + numberofcols[0]]) n = n + numberofcols[0] if self._checklistxoa.count < 1: for s in range(0, len(values_name)): self._checklistxoa.__add__((values_name[s])) if self._checklisttimkiem.count < 1: for s in range(0, len(values_name)): self._checklisttimkiem.__add__((values_name[s])) except: tk.messagebox.showwarning( "Warning", "Không thể đọc file khác excel hoặc đường dẫn không đúng") #event tab 2 #event for thêm button def __add(self): var = str(self._diachi.value).strip().split(',') var2 = var[0].split('/') var3 = var2[0] if self._list.rows_count < 1: messagebox.showwarning("Warning", "Không có list để thêm vào") elif len(var3) == 0 \ or (not var3[0].isdigit() and len(var3) == 1 ) \ or ( not var3[0:(len(var3) -1 )].isdigit() and len(var3) > 1 ) : messagebox.showwarning("Warning", "Địa chỉ không hợp lệ") elif not str(self._dientich.value).strip().isnumeric(): messagebox.showwarning("Warning", "Diện tích không hợp lệ") elif not str(self._chusohuuhientai.value).strip(): messagebox.showwarning("Warning", "Chủ sở hữu trống") elif not str(self._loainha.value).strip(): messagebox.showwarning("Warning", "loại nhà trống") elif not str(self._mucdichsudung.value).strip(): messagebox.showwarning("Warning", "mục đích sử dụng trống") elif not str(self._giatien.value).strip(): messagebox.showwarning("Warning", "giá tiền trống") else: index = self._list.rows_count values.append(index) values.append(str(self._diachi.value)) values.append(str(self._dientich.value)) values.append(str(self._chusohuuhientai.value)) values.append(str(self._loainha.value)) values.append(str(self._mucdichsudung.value)) values.append(str(self._giatien.value)) if var3.isdigit(): fsqc.append(int(var3[0:(len(var3))])) else: fsqc.append(int(var3[0:(len(var3) - 1)])) heap_sort() self._refresh() #event tab 3 #search : def __search(self): if self._list.rows_count <= 1: messagebox.showwarning("Warning", "Danh sách rỗng") elif not self._timkiem.value: messagebox.showwarning("Warning", "Vui lòng nhập nội dung tìm kiếm") elif self._checklisttimkiem.selected_row_index == -1: messagebox.showwarning("Warning", "Vui lòng chọn tiêu chí cần xóa") self._checklisttimkiem.show() self._buttonhideshowtimkiem.icon = 'img/hide_icon.png' self._buttonhideshowtimkiem.label = 'Ẩn tiêu chí' else: self._refresh() s = 1 while s < self._list.rows_count: if not (str(self._timkiem.value).strip()) in str( self._list.get_value( self._checklisttimkiem.selected_row_index, s)): self._list.__sub__(s) s = s - 1 s = s + 1 def _huybo(self): self._refresh() def _buthideshowtimkiem(self): if not values_name: tk.messagebox.showwarning("Warning", "Không có list để chọn tiêu chí") elif str(self._buttonhideshowtimkiem.label) == 'Ẩn tiêu chí': self._checklisttimkiem.hide() self._buttonhideshowtimkiem.icon = 'img/show.png' self._buttonhideshowtimkiem.label = 'Hiển thị tiêu chí' elif str(self._buttonhideshowtimkiem.label) == 'Hiển thị tiêu chí': self._checklisttimkiem.show() self._buttonhideshowtimkiem.icon = 'img/hide_icon.png' self._buttonhideshowtimkiem.label = 'Ẩn tiêu chí' #delete def __xoa(self): if self._list.rows_count <= 1: messagebox.showwarning("Warning", "Danh sách rỗng") elif not self._textxoa.value: messagebox.showwarning("Warning", "Vui lòng nhập nội dung cần xóa") elif self._checklistxoa.selected_row_index == -1: messagebox.showwarning("Warning", "Vui lòng chọn tiêu chí cần xóa") self._checklistxoa.show() self._buttonhideshowxoa.icon = 'img/hide_icon.png' self._buttonhideshowxoa.label = 'Ẩn tiêu chí' else: result = messagebox.askokcancel('Warning', 'Bạn có chắc muốn xóa?') startvaluescount = len(values) if result == 1: s = 1 while s < len(values): if (str(self._textxoa.value).strip()) in str( values[s + self._checklistxoa.selected_row_index - 1]): del fsqc[s // 7] del values[(s - 1):(s + 6)] s = s - 7 s = s + 7 self._refresh() if startvaluescount > len(values): messagebox.showinfo("Sucess!!", "Đã xóa dữ liệu thành công") self._checklistxoa.hide() self._buttonhideshowxoa.icon = 'img/show.png' self._buttonhideshowxoa.label = 'Hiển thị tiêu chí' else: messagebox.showinfo( "Opps", "Nội dung cần xóa không có trong cột tiêu chí trong danh sách" ) def _buthideshowxoa(self): if not values_name: tk.messagebox.showwarning("Warning", "Không có list để chọn tiêu chí") elif str(self._buttonhideshowxoa.label) == 'Ẩn tiêu chí': self._checklistxoa.hide() self._buttonhideshowxoa.icon = 'img/show.png' self._buttonhideshowxoa.label = 'Hiển thị tiêu chí' elif str(self._buttonhideshowxoa.label) == 'Hiển thị tiêu chí': self._checklistxoa.show() self._buttonhideshowxoa.icon = 'img/hide_icon.png' self._buttonhideshowxoa.label = 'Ẩn tiêu chí' #event tab 4 #event _butxuat def __xuat(self): # kiểm tra đường dẫn if not os.path.isdir(self._directory.value): messagebox.showwarning("Warning", "đường dẫn ko có") elif not self._tenfilexuat.value: messagebox.showwarning("Warning", "tên file rỗng") elif not values and not values_name: messagebox.showwarning("Warning", "không có dữ liệu để xuất") else: try: os.makedirs(self._tenfilexuat.value) os.rmdir(self._tenfilexuat.value) if os.path.isfile(self._directory.value + '/' + self._tenfilexuat.value + '.xls'): result = messagebox.askokcancel( 'Warning', 'File đã tồn tại bạn có muốn ghi đè lên ?') if result == 1: write(self._directory.value, self._tenfilexuat.value) myfile = Path(self._directory.value + '/' + self._tenfilexuat.value + '.xls') if myfile.is_file(): messagebox.showinfo("Sucess!!", "Đã xuất file thành công") else: result = messagebox.askokcancel('Warning', 'Bạn có chắc muốn xuất?') if result == 1: write(self._directory.value, self._tenfilexuat.value) myfile = Path(self._directory.value + '/' + self._tenfilexuat.value + '.xls') if myfile.is_file(): messagebox.showinfo("Sucess!!", "Đã xuất file thành công") except OSError: messagebox.showwarning( "Warning", "Tên file không hợp lệ hoặc đang được mở bởi ứng dụng khác" ) #event tab 5 #event _butmerge def _merge(self): if self._list.rows_count < 1: messagebox.showwarning("Warning", "Danh sách rỗng") else: result = messagebox.askokcancel('Warning', 'Bạn có chắc muốn gộp?') if result == 1: for i in range(1, len(valuesimport), 7): n = False for s in range(1, len(values), 7): if valuesimport[i] == values[s]: f = self._checklist.checked_indexes for c in range(0, len(f), 1): values[s + int(f[c]) - 1] = valuesimport[i + int(f[c]) - 1] n = True if not n: fsqc.append(fsqcimport[int(i / 7)]) for s in range(i - 1, i + 6): values.append(valuesimport[s]) self._refresh() for i in range(0, self._listmerge.rows_count): self._listmerge.__sub__(i) for j in range(0, self._listmerge.rows_count): self._listmerge.__sub__(j) self._clearimportdata() self._checklist.hide() self._buttonhideshow.icon = 'img/show.png' self._buttonhideshow.label = 'Hiển thị tùy chọn' self._buttonremovemerge.hide() self._butmerge.hide() self._buttonhideshow.hide() tk.messagebox.showinfo("Success", "Đã merge thành công") #event _buttonremovemerge def _remove(self): if self._listmerge.rows_count < 1: tk.messagebox.showwarning("Warning", "Đã xóa hết!") else: for i in range(0, self._listmerge.rows_count): self._listmerge.__sub__(i) for j in range(0, self._listmerge.rows_count): self._listmerge.__sub__(j) self._clearimportdata() self._checklist.clear() self._buttonremovemerge.hide() self._buttonhideshow.hide() self._checklist.hide() self._butmerge.hide() #event _buttonhideshow def _buthideshow(self): if str(self._buttonhideshow.label) == 'Ẩn tùy chọn': self._checklist.hide() self._buttonhideshow.icon = 'img/show.png' self._buttonhideshow.label = 'Hiển thị tùy chọn' elif str(self._buttonhideshow.label) == 'Hiển thị tùy chọn': self._checklist.show() self._buttonhideshow.icon = 'img/hide_icon.png' self._buttonhideshow.label = 'Ẩn tùy chọn' #event _buttonimport def _import(self): if not self._filemerge.value: tk.messagebox.showwarning("Warning", "Đường dẫn trống") else: path = self._filemerge.value try: importexcel(path) self._listmerge.value = [values_nameimport] n = 0 for i in range(int(len(valuesimport) / numberofcolsimport[0])): self._listmerge.__add__( valuesimport[n:n + numberofcolsimport[0]]) n = n + numberofcolsimport[0] if self._checklist.count < 1: for s in range(0, len(values_nameimport)): self._checklist.__add__((values_nameimport[s], True)) if self._listmerge and not self._buttonhideshow.visible: if str(self._buttonhideshow.label) == 'Ẩn tùy chọn': self._buttonhideshow.icon = 'img/show.png' self._buttonhideshow.label = 'Hiển thị tùy chọn' self._buttonhideshow.show() self._buttonremovemerge.show() self._butmerge.show() except: tk.messagebox.showwarning( "Warning", "Không thể đọc file khác excel hoặc đường dẫn không đúng") #reusable function def _refresh(self): for i in range(1, self._list.rows_count): self._list.__sub__(i) for j in range(1, self._list.rows_count): self._list.__sub__(j) n = 0 for i in range(int(len(values) / numberofcols[0])): self._list.__add__(values[n:n + numberofcols[0]]) n = n + numberofcols[0] # update STT for s in range(1, self._list.rows_count): values[(s - 1) * 7] = s self._list.set_value(0, s, s) def _clearimportdata(self): fsqcimport.clear() valuesimport.clear() sqcimport.clear() numberofcolsimport.clear() values_nameimport.clear() self._checklist.clear()