diff --git a/clusterview2.ui b/clusterview2.ui index 1f1316a..ee96aff 100644 --- a/clusterview2.ui +++ b/clusterview2.ui @@ -130,26 +130,16 @@ - + false - Unweighted Clustering + K-Means Clustering - - - false - - - Weighted Clustering - - - - Reset diff --git a/clusterview2/mode.py b/clusterview2/mode.py index f7699d3..fe9a2f7 100644 --- a/clusterview2/mode.py +++ b/clusterview2/mode.py @@ -13,5 +13,4 @@ class Mode(Enum): MOVE = 3 DELETE = 4 LOADED = 5 - UNWEIGHTED_CLUSTERING = 6 - WEIGHTED_CLUSTERING = 7 + CLUSTERING = 6 diff --git a/clusterview2/points.py b/clusterview2/points.py index 5c75c38..ca61637 100644 --- a/clusterview2/points.py +++ b/clusterview2/points.py @@ -69,6 +69,10 @@ class Point(BasePoint): def weight(self): return self._weight + @weight.setter + def weight(self, weight): + return self._weight + @property def cluster(self): return self._cluster diff --git a/clusterview2/ui/mode_handlers.py b/clusterview2/ui/mode_handlers.py index 1ee1dd1..3240581 100644 --- a/clusterview2/ui/mode_handlers.py +++ b/clusterview2/ui/mode_handlers.py @@ -2,6 +2,7 @@ import random from PyQt5.QtCore import QEvent, Qt from PyQt5.QtGui import QCursor +from PyQt5.QtWidgets import QErrorMessage, QInputDialog from kmeans.algorithms import k_means @@ -117,25 +118,36 @@ def _handle_add_point(ctx, event): def _handle_edit_point(ctx, event): - # TODO: This function and delete definitely need to make sure they are - # on a point we have. - # - # Since points are unique consider a hashmap of points to make O(1) - # lookups for addition and deletion. This list can be maintained here - # in this module. It should be a dictionary - from point to - # attributes in the case of algorithms that require points to have - # weights or something. - # - # Should move the associated point in the list to the new location if - # applicable. - _handle_info_updates(ctx, event) PointManager.point_set.clear_selection() - # Store old x, y from event - set_drawing_event(event) - ctx.update() - # after this remove the point from the list + if (event.button() == Qt.LeftButton and + event.type() == QEvent.MouseButtonPress): + + # See if a point was hit + point = None + + for p in PointManager.point_set.points: + if p.hit(event.x(), event.y()): + point = p + break + + # Get point weight from user and assign it to the point. + if point is not None: + value, ok = QInputDialog.getDouble(None, 'Weight', 'Weight(Float): ', 1, 1, 3000, 1) + + if ok: + if not isinstance(value, float): + error_dialog = QErrorMessage() + error_dialog.showMessage('Point weight must be a floating point value.') + error_dialog.exec_() + + else: + point.weight = value + + # Store old x, y from event + set_drawing_event(event) + ctx.update() def ogl_keypress_handler(ctx, event): @@ -366,5 +378,5 @@ MODE_HANDLER_MAP = { Mode.EDIT: _handle_edit_point, Mode.MOVE: _handle_move_points, Mode.DELETE: _handle_delete_point, - Mode.UNWEIGHTED_CLUSTERING: _handle_clustering + Mode.CLUSTERING: _handle_clustering } diff --git a/clusterview2/ui/opengl_widget.py b/clusterview2/ui/opengl_widget.py index a53da3d..90fb655 100644 --- a/clusterview2/ui/opengl_widget.py +++ b/clusterview2/ui/opengl_widget.py @@ -182,15 +182,12 @@ def paint_gl(): if (__current_context.mode is Mode.ADD or __current_context.mode is Mode.DELETE or + __current_context.mode is Mode.EDIT or __current_context.mode is Mode.LOADED or - __current_context.mode is Mode.UNWEIGHTED_CLUSTERING or - __current_context.mode is Mode.WEIGHTED_CLUSTERING): + __current_context.mode is Mode.CLUSTERING): draw_points(PointManager.point_set) - elif __current_context.mode is Mode.EDIT: - raise NotImplementedError('Drawing for EDIT not implemented.') - elif __current_context.mode is Mode.MOVE: # We have to repeatedly draw the points while we are showing the # move box. diff --git a/clusterview2_ui.py b/clusterview2_ui.py index 5c3cb56..959a557 100644 --- a/clusterview2_ui.py +++ b/clusterview2_ui.py @@ -74,17 +74,13 @@ class Ui_MainWindow(object): self.number_of_clusters.setMaximumSize(QtCore.QSize(50, 16777215)) self.number_of_clusters.setObjectName("number_of_clusters") self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.number_of_clusters) - self.unweighted_clustering_button = QtWidgets.QPushButton(self.groupBox_3) - self.unweighted_clustering_button.setEnabled(False) - self.unweighted_clustering_button.setObjectName("unweighted_clustering_button") - self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.unweighted_clustering_button) - self.weighted_clustering_button = QtWidgets.QPushButton(self.groupBox_3) - self.weighted_clustering_button.setEnabled(False) - self.weighted_clustering_button.setObjectName("weighted_clustering_button") - self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.weighted_clustering_button) + self.clustering_button = QtWidgets.QPushButton(self.groupBox_3) + self.clustering_button.setEnabled(False) + self.clustering_button.setObjectName("clustering_button") + self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.clustering_button) self.reset_button = QtWidgets.QPushButton(self.groupBox_3) self.reset_button.setObjectName("reset_button") - self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.reset_button) + self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.reset_button) self.verticalLayout.addWidget(self.groupBox_3) spacerItem = QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed) self.verticalLayout.addItem(spacerItem) @@ -167,8 +163,7 @@ class Ui_MainWindow(object): self.groupBox.setTitle(_translate("MainWindow", "Point List")) self.groupBox_3.setTitle(_translate("MainWindow", "Solver")) self.label_2.setText(_translate("MainWindow", "Clusters")) - self.unweighted_clustering_button.setText(_translate("MainWindow", "Unweighted Clustering")) - self.weighted_clustering_button.setText(_translate("MainWindow", "Weighted Clustering")) + self.clustering_button.setText(_translate("MainWindow", "K-Means Clustering")) self.reset_button.setText(_translate("MainWindow", "Reset")) self.groupBox_2.setTitle(_translate("MainWindow", "Canvas Information")) self.label.setText(_translate("MainWindow", "Mouse Position:")) diff --git a/main_window.py b/main_window.py index e4ae60e..9f2287b 100644 --- a/main_window.py +++ b/main_window.py @@ -83,7 +83,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): self.point_list_widget.itemClicked.connect(partial(item_click_handler, self)) - self.unweighted_clustering_button.clicked.connect(self._unweighted_clustering) + self.clustering_button.clicked.connect(self._clustering) self.number_of_clusters.valueChanged.connect(self._clustering_enabled) self.reset_button.clicked.connect(self._reset) @@ -166,9 +166,9 @@ class MainWindow(QMainWindow, Ui_MainWindow): clear_selection() self.opengl_widget.update() - def _unweighted_clustering(self): + def _clustering(self): clear_selection() - self._mode = Mode.UNWEIGHTED_CLUSTERING + self._mode = Mode.CLUSTERING self.opengl_widget.setCursor(QCursor(Qt.CursorShape.ArrowCursor)) self.status_bar.showMessage('UNWEIGHTED CLUSTERING') self.opengl_widget.update() @@ -177,10 +177,13 @@ class MainWindow(QMainWindow, Ui_MainWindow): self._off_mode() self.number_of_clusters.setEnabled(True) self.number_of_clusters.setValue(0) - self.unweighted_clustering_button.setEnabled(False) - self.weighted_clustering_button.setEnabled(False) + self.clustering_button.setEnabled(False) self.clustering_solved = False PointManager.clusters = [] + + for point in PointManager.point_set.points: + point.weight = 1.0 + reset_colors() def _generate_random_points(self): @@ -200,8 +203,7 @@ class MainWindow(QMainWindow, Ui_MainWindow): refresh_point_list(self) def _clustering_enabled(self): - self.unweighted_clustering_button.setEnabled(self.number_of_clusters.value() > 0) - self.weighted_clustering_button.setEnabled(self.number_of_clusters.value() > 0) + self.clustering_button.setEnabled(self.number_of_clusters.value() > 0) @property def mode(self):