class Graph2Event(BaseWidget): def __init__(self, timeline=None): super(Graph2Event, self).__init__('Graph to event', parent_win=timeline) self.setContentsMargins(10, 10, 10, 10) self._timeline = timeline # Definition of the forms fields self._graphs_list = ControlList('Graphs list (try double click)') self._equation = ControlTextArea('Equation') self._eventname = ControlText('Event name', 'New event') self._rownumber = ControlNumber('Row number', 0, 0, 1000) self._mindiff = ControlNumber('Minimum of frames', 0, 0, 1000000) self._genevts_btn = ControlButton('Generate events') self._formset = [ (['_graphs_list'], '||', [ ('_eventname', '_rownumber', '_mindiff'), '_equation', '_genevts_btn', ]), ] self._graphs_list.cell_double_clicked_event = self.__cell_double_clicked_evt self._graphs_list.readonly = True self._graphs_list.select_entire_row = True self._genevts_btn.value = self.__generage_events_evt def __add__(self, other): self._graphs_list += [other.name] return self def __sub__(self, other): self._graphs_list -= other return self def rename_graph(self, graph_index, newname): self._graphs_list.set_value(graph_index, 0, newname) @property def graphs(self): return self._timeline._charts def __cell_double_clicked_evt(self, row, column): if len(self._equation.value.strip()) == 0: self._equation.value += '[{0}]'.format( self._graphs_list.value[row][column]) else: self._equation.value += ' and [{0}]'.format( self._graphs_list.value[row][column]) def __generage_events_evt(self): if len(self._eventname.value.strip()) == 0: QMessageBox.warning(self, "Attention!", 'The event name cannot be empty') return if len(self._equation.value.strip()) == 0: QMessageBox.warning(self, "Attention!", 'The equation cannot be empty') return max_frame = 0 equation = self._equation.value for i, values in enumerate(self._graphs_list.value): graphname = '[{0}]'.format(values[0]) if graphname in equation: max_frame = max(max_frame, len(self.graphs[i])) equation = equation.replace(graphname, 'graphs[{0}][i]'.format(i)) graphs = self.graphs last_index = None last_value = False try: for i in range(max_frame): value = eval(equation) if not last_value and bool(value): last_index = i last_value = True if last_value and not bool(value): if (i - 1 - last_index) >= self._mindiff.value: self._timeline.addPeriod( [last_index, i - 1, self._eventname.value], int(self._rownumber.value)) last_value = False last_index = None if last_value and (max_frame - last_index) >= self._mindiff.value: self._timeline.addPeriod( [last_index, max_frame, self._eventname.value], int(self._rownumber.value)) except Exception as e: QMessageBox.warning(self, "Error!", str(e)) self._timeline.repaint()
class GraphsProperties(BaseWidget): def __init__(self, timelineWidget=None, parent_win=None): super(GraphsProperties, self).__init__('Graphs properties', parent_win=parent_win) self.setContentsMargins(10, 10, 10, 10) self._mainwindow = parent_win self._timeline = timelineWidget #self.setMaximumWidth(300) # Definition of the forms fields self._graphs_list = ControlList('Graphs list') self._name = ControlText('Name') self._min_value = ControlNumber('Min', default=0, minimum=-sys.float_info.max, maximum=sys.float_info.max) self._max_value = ControlNumber('Max', default=0, minimum=-sys.float_info.max, maximum=sys.float_info.max) self._values_zoom = ControlSlider('Amplitude', default=100, minimum=60, maximum=400) self._values_top = ControlNumber('Bottom', default=0, minimum=-1000, maximum=1000) self._remove_graph_btn = ControlButton('Remove graph') self._value = ControlLabel() self._pickcolor = ControlButton('Pick color', default=self.__pickcolor_evt) self._graphs_list.readonly = True self._formset = [ (['_graphs_list', '_remove_graph_btn'], '||', [ ' ', '_name', ('_min_value', '_max_value', ' '), ('_values_top', '_pickcolor'), '_values_zoom', 'info:Choose one graph and move the mouse over \nthe timeline to visualize the coordenates.', '_value' ]), ] self._graphs_list.select_entire_row = True self._graphs_list.item_selection_changed_event = self.__graphs_list_selection_changed self._loaded = False self._current_selected_graph = None self._name.changed_event = self.__save_graphs_changes self._min_value.changed_event = self.__save_graphs_changes self._max_value.changed_event = self.__save_graphs_changes self._values_zoom.changed_event = self.__save_graphs_changes self._values_top.changed_event = self.__save_graphs_changes self._name.enabled = False self._min_value.enabled = False self._max_value.enabled = False self._values_zoom.enabled = False self._values_top.enabled = False self._remove_graph_btn.enabled = False self._pickcolor.enabled = False self._remove_graph_btn.value = self.__remove_chart def __add__(self, other): self._graphs_list += [other.name] return self def __sub__(self, other): self._graphs_list -= other return self def rename_graph(self, graph_index, newname): self._graphs_list.set_value(graph_index, 0, newname) @property def selected_graph(self): index = self._graphs_list.selected_row_index return self._timeline._charts[index] if (index is not None) else None @property def coordenate_text(self): return self._value @coordenate_text.setter def coordenate_text(self, value): self._value.value = str(value) if value else '' def show(self): super(GraphsProperties, self).show() self._loaded = False def __pickcolor_evt(self): color = QColorDialog.getColor(self._current_selected_graph._color, self, 'Pick a color for the graph') self._current_selected_graph._color = color self._timeline.repaint() def __remove_chart(self): index = self._graphs_list.selected_row_index if index is not None: self._current_selected_graph = None self._timeline._charts.pop(index) self._loaded = False self._name.enabled = False self._min_value.enabled = False self._max_value.enabled = False self._values_zoom.enabled = False self._values_top.enabled = False self._remove_graph_btn.enabled = False self._pickcolor.enabled = False self._timeline.repaint() self._mainwindow -= index def __graphs_list_selection_changed(self): graph = self.selected_graph self._updating_properties = True if graph is not None: graphmin = np.asscalar(graph.graph_min) if isinstance( graph.graph_min, np.generic) else graph.graph_min graphmax = np.asscalar(graph.graph_max) if isinstance( graph.graph_max, np.generic) else graph.graph_max exponent_min = abs(decimal.Decimal(graphmin).as_tuple().exponent) exponent_max = abs(decimal.Decimal(graphmax).as_tuple().exponent) exponent_min = 4 if exponent_min > 4 else exponent_min exponent_max = 4 if exponent_min > 4 else exponent_min self._name.value = graph.name self._min_value.decimals = exponent_min self._min_value.value = graph.graph_min self._max_value.decimals = exponent_max self._max_value.value = graph.graph_max self._values_zoom.value = graph._zoom * 100.0 self._values_top.value = graph._top self._loaded = True self._name.enabled = True self._min_value.enabled = True self._max_value.enabled = True self._values_zoom.enabled = True self._values_top.enabled = True self._remove_graph_btn.enabled = True self._pickcolor.enabled = True self._current_selected_graph = graph del self._updating_properties def __save_graphs_changes(self): if hasattr(self, '_updating_properties'): return if self._loaded and self._current_selected_graph is not None: graph = self._current_selected_graph #logger.debug('Before: Min: {0} | Max: {1} Zoom: {2}'.format(graph.graph_min, graph.graph_max,graph.zoom ) ) graph.name = self._name.value graph.graph_min = self._min_value.value graph.graph_max = self._max_value.value graph.zoom = self._values_zoom.value / 100.0 graph.top = self._values_top.value logger.debug('Min: {0} | Max: {1} Zoom: {2}'.format( graph.graph_min, graph.graph_max, graph.zoom)) self._timeline.repaint() @property def graphs(self): return self._timeline.graphs def mouse_moveover_timeline_event(self, event): graph = self.selected_graph if graph is not None: graph.mouse_move_evt(event, 0, self.height())
class GeometryManualDesigner(BaseWidget): def __init__(self, title, parent=None): super(GeometryManualDesigner, self).__init__(title, parent_win=parent) self._threshold_win = None self._start_point = None self._end_point = None self._selected_poly = None self._selected_point = None self._video = ControlFile("Video file") self._player = ControlPlayer("Video") self._remove = ControlButton("Remove") self._square = ControlButton("Square", checkable=True) self._circle = ControlButton("Circle", checkable=True) self._threshold = ControlButton("Threshold") self._export = ControlButton("Export") self._import = ControlButton("Import") self._polygons = ControlList('Polygons') self._apply = ControlButton('Apply') self._formset = [ '_video', "_player", ("_square", "_circle", "_threshold", " ", "_remove", " ", "_export", "_import"), "=", "_polygons", '_apply' ] self._video.changedchanged_event = self.videoSelected self._square.value = self.square_toggle self._circle.value = self.circle_toggle self._remove.value = self.remove_clicked self._export.value = self.export_clicked self._import.value = self.import_clicked self._threshold.value = self.threshold_btn_click self._player.drag_event = self.on_player_drag_in_video_window self._player.end_drag_event = self.on_player_end_drag_in_video_window self._player.click_event = self.on_player_click_in_video_window self._player.double_click_event = self.on_player_double_click_in_video_window self._player.process_frame_event = self.process_frame self._player.key_release_event = self.on_player_key_release self._apply.hide() def on_player_key_release(self, event): if event.key() == QtCore.Qt.Key_Delete: if self._selected_poly != None and self._selected_point != None: poly = self._polygons.get_value(1, self._selected_poly) try: points = list(eval(poly)) p = points.pop(self._selected_point) self._polygons.set_value(1, self._selected_poly, str(points)[1:-1]) if not self._player.is_playing: self._player.refresh() except: pass def export_clicked(self): filename = str(QFileDialog.getSaveFileName(self, 'Choose a file', '')) if filename != "": output = open(filename, 'w') for values in self._polygons.value: output.write((';'.join(values) + '\n')) output.close() def import_clicked(self): filename = str(QFileDialog.getOpenFileName(self, 'Choose a file', '')) if filename != "": infile = open(filename, 'r') polygons = [] for line in infile: values = line.split(';') name = values[0] poly = values[1] polygons.append((name, poly)) self._polygons.value += polygons def process_frame(self, frame): rows = self._polygons.value for objIndex, obj in enumerate(rows): points = eval(obj[1]) cv2.polylines(frame, [np.array(points, np.int32)], True, (0, 255, 0), 2, lineType=cv2.LINE_AA) for pointIndex, point in enumerate(points): if self._selected_point == pointIndex and objIndex == self._selected_poly: cv2.circle(frame, point, 4, (0, 0, 255), 2) else: cv2.circle(frame, point, 4, (0, 255, 0), 2) if self._start_point and self._end_point: if self._square.checked: cv2.rectangle(frame, self._start_point, self._end_point, (233, 44, 44), 2) elif self._circle.checked and self._end_point[ 0] > self._start_point[0] and self._end_point[ 1] > self._start_point[1]: width = self._end_point[0] - self._start_point[0] height = self._end_point[1] - self._start_point[1] center = (self._start_point[0] + width / 2, self._start_point[1] + height / 2) cv2.ellipse(frame, (center, (width, height), 0), (233, 44, 44), 2) return frame def selectPoint(self, x, y): rows = self._polygons.value for objIndex, obj in enumerate(rows): try: mouseCoord = (x, y) points = eval(obj[1]) for pointIndex, point in enumerate(points): if pointsDistance(mouseCoord, point) <= 5: self._selected_point = pointIndex self._selected_poly = objIndex return self._selected_point = None self._selected_poly = None except: pass def get_intersection_point_distance(self, test_point, point1, point2): p1 = np.float32(point1) p2 = np.float32(point2) p3 = np.float32(test_point) dist = np.linalg.norm(np.cross(p2 - p1, p1 - p3)) / np.linalg.norm(p2 - p1) return dist def on_player_double_click_in_video_window(self, event, x, y): mouse = (int(x), int(y)) rows = self._polygons.value distances = [] for obj_index, obj in enumerate(rows): try: points = list(eval(obj[1])) n_points = len(points) for point_index, point in enumerate(points): next_point = points[(point_index + 1) % n_points] distance = self.get_intersection_point_distance( mouse, point, next_point) if distance <= 5: vector = next_point[0] - point[0], next_point[ 1] - point[1] center = point[0] + vector[0] / 2, point[ 1] + vector[1] / 2 radius = pointsDistance(center, point) mouse_distance = pointsDistance(center, mouse) if mouse_distance < radius: distances.append( (distance, obj_index, point_index)) except: pass if len(distances) > 0: distances = sorted(distances, key=lambda x: x[0]) obj_index = distances[0][1] point_index = distances[0][2] points = list(eval(rows[obj_index][1])) points.insert(point_index + 1, mouse) self._polygons.set_value(1, obj_index, str(points)[1:-1]) self._selected_poly = obj_index self._selected_point = point_index + 1 if not self._player.is_playing: self._player.refresh() def on_player_click_in_video_window(self, event, x, y): self._selected_poly = None self._selected_point = None if not self._square.checked and not self._circle.checked: self.selectPoint(int(x), int(y)) def on_player_drag_in_video_window(self, startPoint, endPoint): self._start_point = (int(startPoint[0]), int(startPoint[1])) self._end_point = (int(endPoint[0]), int(endPoint[1])) if self._selected_poly != None and self._selected_point != None: poly = self._polygons.get_value(1, self._selected_poly) try: points = list(eval(poly)) points[self._selected_point] = self._end_point self._polygons.set_value(1, self._selected_poly, str(points)[1:-1]) except Exception as e: print(e) if not self._player.is_playing: self._player.refresh() def on_player_end_drag_in_video_window(self, startPoint, endPoint): self._start_point = int(startPoint[0]), int(startPoint[1]) self._end_point = int(endPoint[0]), int(endPoint[1]) points = None if self._square.checked: points = createRectanglePoints(self._start_point, self._end_point) elif self._circle.checked and self._end_point[0] > self._start_point[ 0] and self._end_point[1] > self._start_point[1]: points = createEllipsePoints(self._start_point, self._end_point) if points: self._polygons += [ "Poly_%d" % self._polygons.rows_count, str(points)[1:-1] ] self._start_point = None self._end_point = None self._square.checked = False self._circle.checked = False if not self._player.is_playing: self._player.refresh() def __add_contours_from_threshold_win(self, contours): for contour in contours: if contour.any(): points = [tuple(p[0]) for p in contour.tolist()] self._polygons += [ "Poly_%d" % self._polygons.rows_count, str(points)[1:-1] ] def videoSelected(self): self._player.value = self._video.value def square_toggle(self, checked): if checked: self._circle.checked = False def circle_toggle(self, checked): if checked: self._square.checked = False def threshold_btn_click(self): if self._threshold_win is None: self._threshold_win = GeometryFromThreshold(self) self._threshold_win.add_contours = self.__add_contours_from_threshold_win self._threshold_win.show() if len(self._video.value) > 0: self._threshold_win._filename.value = self._video.value def remove_clicked(self): self._polygons -= -1 #Remove the selected row if not self._player.is_playing: self._player.refresh() @property def geometries(self): polys = [] rows = self._polygons.value for objIndex, obj in enumerate(rows): points = eval(obj[1]) polys.append([obj[0], points]) return polys @geometries.setter def geometries(self, value): self._polygons.value = [] for name, poly in value: points = [tuple(p) for p in poly] self._polygons += [name, str(points)[1:-1]] @property def polygons(self): polys = [] rows = self._polygons.value for objIndex, obj in enumerate(rows): points = eval(obj[1]) polys.append(np.array(points, np.int32)) return np.array(polys) @property def apply_event(self): return self._apply.value @apply_event.setter def apply_event(self, value): self._apply.value = value self._show_apply = value is not None def show(self): super(GeometryManualDesigner, self).show() if hasattr(self, '_show_apply') and self._show_apply: self._apply.show() @property def video_filename(self): return None @video_filename.setter def video_filename(self, value): self._video.hide() self._player.value = value @property def video_capture(self): return self.video_capture.value @video_capture.setter def video_capture(self, value): self._video.hide() self._player.value = value @property def total_n_frames(self): if self._player._value is not None and self._player.value != '': return self._player.max else: return 0
class GraphsEventsGenerator(BaseWidget): def __init__(self, timeline=None): super(GraphsEventsGenerator, self).__init__('Apply a function to the graph values', parent_win=timeline) self.setContentsMargins(10, 10, 10, 10) self._timeline = timeline # Definition of the forms fields self._graphs_list = ControlList('Graphs list (try double click)', readonly=False, select_entire_row=True) self._equation = ControlTextArea('Equation') self._graphname = ControlText('Graph name') self._genevts_btn = ControlButton('Generate graph') self._formset = [ (['_graphs_list'], '||', [ '_graphname', '_equation', '_genevts_btn', ]), ] self._graphs_list.cell_double_clicked_event = self.__cell_double_clicked_evt self._graphs_list.readonly = True self._graphs_list.select_entire_row = True self._genevts_btn.value = self.__generage_events_evt def __add__(self, other): self._graphs_list += [other.name] return self def __sub__(self, other): self._graphs_list -= other return self def rename_graph(self, graph_index, newname): self._graphs_list.set_value(graph_index, 0, newname) @property def graphs(self): return self._timeline._charts def show(self): super(GraphsEventsGenerator, self).show() if len(self._graphname.value.strip()) == 0: self._graphname.value = "generated-graph-{0}".format( len(self._timeline.graphs)) def __cell_double_clicked_evt(self, row, column): if len(self._equation.value.strip()) == 0: self._equation.value += '[{0}]'.format( self._graphs_list.value[row][column]) else: self._equation.value += ' and [{0}]'.format( self._graphs_list.value[row][column]) def __generage_events_evt(self): if len(self._graphname.value.strip()) == 0: QMessageBox.warning(self, "Attention!", 'The graph name cannot be empty') return if len(self._equation.value.strip()) == 0: QMessageBox.warning(self, "Attention!", 'The equation cannot be empty') return max_frame = 0 equation = self._equation.value for i, values in enumerate(self._graphs_list.value): graphname = '[{0}]'.format(values[0]) if graphname in equation: max_frame = max(max_frame, len(self.graphs[i])) equation = equation.replace(graphname, 'graphs[{0}][i]'.format(i)) graphs = self.graphs data = [] try: for i in range(max_frame): try: value = eval(equation) except: value = None data.append((i, value)) self._timeline.add_chart(self._graphname.value, data) self._graphname.value = "generated-graph-{0}".format( len(self._timeline.graphs)) except Exception as e: traceback.print_exc() QMessageBox.warning(self, "Error!", str(e))
class BoardTaskWindow(BoardTask, BaseWidget): """ Define here which fields from the board_task model should appear on the setup configuration window. The model fields shall be defined as UI components like text fields, buttons, combo boxes, etc. You may also assign actions to these components. .. seealso:: This class heavy relies on the corresponding API module. :py:class:`pybpodgui_api.models.setup.board_task.BoardTask` **Properties** states A list of task states associated with this BoardTask. States are defined on the task code. events A list of task events associated with this BoardTask. Events are defined on the task code. variables A list of task variables associated with this BoardTask. Variables are defined on the task code. **Private attributes** _states :class:`pyforms.controls.ControlList` UI list to show BoardTask states. _events :class:`pyforms.controls.ControlList` UI list to show BoardTask events. _vars :class:`pyforms.controls.ControlList` UI list to show BoardTask variables. _sync_btn :class:`pyforms.controls.ControlButton` Button to sync variables with board. Pressing the button fires the event :meth:`BoardTaskWindow.sync_variables`. _load_btn :class:`pyforms.controls.ControlButton` Button to read task variables from board. Pressing the button fires the event :meth:`BoardTaskWindow._BoardTaskWindow__load_task_details`. _formset Describe window fields organization to PyForms. **Methods** """ def __init__(self, setup): BaseWidget.__init__(self, "Variables config for {0}".format(setup.name)) self._var_is_being_added = False self._updvars = ControlCheckBox('Update variables') self._vars = ControlList('Variables', add_function=self.__add_variable, remove_function=self.__remove_variable) BoardTask.__init__(self, setup) self._vars.horizontal_headers = ['NAME', 'TYPE', 'VALUE'] self._vars.data_changed_event = self.__varslist_data_changed_evt self._formset = ['_updvars', '_vars'] self._variable_rule = re.compile('^[A-Z0-9\_]+$') @property def update_variables(self): return self._updvars.value @update_variables.setter def update_variables(self, value): self._updvars.value = value def create_variable(self, name=None, value=None, datatype='string'): return TaskVariableWindow(self, name, value, datatype) def __varslist_data_changed_evt(self, row, col, item): # only verify if the list is being edited if self._var_is_being_added is True: return if col == 0 and item is not None: if not (self._variable_rule.match(item) and item.startswith('VAR_')): self.critical( "The name of the variable should start with VAR_, should be alphanumeric and upper case.", "Error") self._vars.set_value(col, row, 'VAR_{0}'.format(self._vars.rows_count)) elif col == 2: datatype_combo = self._vars.get_value(1, row) datatype = datatype_combo.value if datatype_combo else None if datatype == 'number' and isinstance( item, str) and not item.isnumeric(): self.message("The value should be numeric.", "Error") self._vars.set_value(col, row, '0') def __add_variable(self): self._var_is_being_added = True var = self.create_variable('VAR_{0}'.format(self._vars.rows_count), '0') self._var_is_being_added = False def __remove_variable(self): if self._vars.selected_row_index is not None: var = self.variables[self._vars.selected_row_index] self.variables.remove(var) self._vars -= -1 def before_close(self): return False
class UserWidget(User, BaseWidget): def __init__(self, admin=None, connection=None, flag='', uid='', email='', name='', services={}): super(UserWidget, self).__init__(uid, email, name, services) BaseWidget.__init__(self, 'User') self._admin = admin self._connection = connection self._flag = flag self.changes = [] #0 is name change, 1 is services change if flag == 'edit': self._editBtn = ControlButton('Edit') self._editBtn.value = self._edit elif flag == 'new': self._editBtn = ControlButton('Save') self._editBtn.value = self._save else: self._closeBtn = ControlButton('Close') self._closeBtn.value = self._close if uid != '': self._uid_field = ControlText('User_Key') self._uid_field.value = uid self._email_field = ControlText('Email') self._email_field.readonly = True if email != '': self._email_field.value = email self._name_field = ControlText('Name') self._name_field.readonly = True if name != '': self._name_field.value = name self._services = services self._services_field = ControlList('Services') self._services_field.readonly = True self._services_field.horizontal_headers = ['Service', 'Value'] #self._services_field.cell_double_clicked_event = None if services != {}: for i in services: self._services_field.__add__([i, services[i]]) def _edit(self): self._editBtn.label = 'Save' self._editBtn.value = self._save self._email_field.readonly = False self._name_field.readonly = False self._services_field.readonly = False self._services_field.cell_double_clicked_event = self._toggle def _save(self): if self.parent != None: self.name = self._name_field.value self.email = self._email_field.value self.services = self._services self.uid = self._uid_field.value if self._flag == 'edit': self.parent._update_user(self) elif self._flag == 'new': self.parent._add_User(self) self._close() def _toggle(self, row, column): val = self._services_field.get_value(column, row) if val == True: self._services_field.set_value(column, row, False) self._services[self._services_field.get_value(0, row)] = False else: self._services_field.set_value(column, row, True) self._services[self._services_field.get_value(0, row)] = True def _close(self): close_win(self)
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()