From 2c4a24b6570d33c59b726dcda63c1b4dfe6cc7bb Mon Sep 17 00:00:00 2001 From: Daniel Kratzert <dkratzert@gmx.de> Date: Sun, 26 Nov 2023 14:53:20 +0100 Subject: [PATCH] Adds edit button for edit fields --- finalcif/gui/custom_classes.py | 4 +-- finalcif/gui/edit_button.py | 66 ++++++++++++++++++++++++++++++++++ finalcif/gui/plaintextedit.py | 60 ++++++++++++++++++++++++++++--- 3 files changed, 124 insertions(+), 6 deletions(-) create mode 100644 finalcif/gui/edit_button.py diff --git a/finalcif/gui/custom_classes.py b/finalcif/gui/custom_classes.py index 541efc8c..0b34f716 100644 --- a/finalcif/gui/custom_classes.py +++ b/finalcif/gui/custom_classes.py @@ -11,12 +11,13 @@ from finalcif.cif.text import retranslate_delimiter from finalcif.gui.combobox import MyComboBox from finalcif.gui.dialogs import show_keyword_help +from finalcif.gui.edit_button import FloatingButtonWidget from finalcif.gui.mixins import ItemTextMixin from finalcif.gui.plaintextedit import MyQPlainTextEdit white = QColor(255, 255, 255) light_green = QColor(217, 255, 201) -light_blue = QColor(220, 232, 247) +light_blue = QColor(249, 249, 249) blue = QColor(102, 150, 179) yellow = QColor(250, 247, 150) # #faf796 @@ -25,7 +26,6 @@ class Column(IntEnum): CIF = 0 DATA = 1 EDIT = 2 - BUTTON = 3 DEBUG = False diff --git a/finalcif/gui/edit_button.py b/finalcif/gui/edit_button.py new file mode 100644 index 00000000..26303bdf --- /dev/null +++ b/finalcif/gui/edit_button.py @@ -0,0 +1,66 @@ +# Create a QTextedit widget with a button to open a file dialog +# to select a file to be inserted into the QTextedit widget +# The file dialog is opened by pressing the button. +# The button should be placed above the QTextedit widget and appear on mouse over. + +from PyQt5 import QtWidgets, QtCore, QtGui +import os +import sys + + +class FloatingButtonWidget(QtWidgets.QPushButton): + floatingButtonClicked = QtCore.pyqtSignal() + + def __init__(self, parent=None, *args, **kwargs): + super().__init__(parent=parent, *args, **kwargs) + self.setText('edit') + self.paddingLeft = 2 + self.paddingTop = 2 + self.setFixedSize(24, 16) + self.setFlat(True) + self.setStyleSheet(f'''QPushButton {{background-color: {QtGui.QColor(220, 232, 247).name()}; + padding-bottom: 1px; + border-radius: 5px; + font-size: 11px; + border: 1px solid {QtGui.QColor(170, 172, 177).name()}; + }} + ''') + + def update_position(self): + """Update the position of the button to be placed in the bottom right corner of the parent widget. + """ + self.move(self.parent().width() - self.width() - self.paddingLeft, + self.parent().height() - self.height() - self.paddingTop) + + def mousePressEvent(self, event): + self.floatingButtonClicked.emit() + + +class OverlayTestEdit(QtWidgets.QTextEdit): + + def __init__(self, parent=None): + super().__init__(parent) + self.edit_button = FloatingButtonWidget(parent=self) + # The button should be placed over the QTextedit widget as overlay and appear on mouse over. + self.edit_button.hide() + self.edit_button.update_position() + + def resizeEvent(self, event): + self.edit_button.update_position() + super().resizeEvent(event) + + def enterEvent(self, a0): + print('enter') + self.edit_button.show() + + def leaveEvent(self, a0): + print('leave') + self.edit_button.hide() + + +if __name__ == '__main__': + app = QtWidgets.QApplication(sys.argv) + window = OverlayTestEdit() + window.resize(130, 30) + window.show() + sys.exit(app.exec_()) diff --git a/finalcif/gui/plaintextedit.py b/finalcif/gui/plaintextedit.py index c94c5f8d..f854b0b5 100644 --- a/finalcif/gui/plaintextedit.py +++ b/finalcif/gui/plaintextedit.py @@ -3,10 +3,13 @@ from functools import cache from typing import TYPE_CHECKING +from PyQt5 import QtCore from PyQt5.QtCore import pyqtSignal, Qt, QObject, QEvent, QSize from PyQt5.QtGui import QTextOption, QFontMetrics, QContextMenuEvent, QFont, QColor from PyQt5.QtWidgets import QPlainTextEdit, QFrame, QApplication, QAbstractScrollArea +from numpy import random +from finalcif.gui.edit_button import FloatingButtonWidget from finalcif.gui.new_key_dialog import NewKey if TYPE_CHECKING: @@ -17,7 +20,6 @@ class Column(IntEnum): CIF = 0 DATA = 1 EDIT = 2 - BUTTON = 3 class MyQPlainTextEdit(QPlainTextEdit): @@ -33,9 +35,9 @@ def __init__(self, parent=None, *args, **kwargs): """ Plaintext edit field for most of the table cells. """ - super().__init__(parent, *args, **kwargs) - self.setParent(parent) + super().__init__(parent=parent, *args, **kwargs) self.cif_key = '' + self.edit_button = None font = QFont() font.setPointSize(self.document().defaultFont().pointSize() + 1) self.setFont(font) @@ -91,7 +93,11 @@ def copy_vhead_item(self, row): @property def row(self) -> int: - return self.parent.vheaderitems.index(self.cif_key) + return self.parent.indexAt(self.pos()).row() + + @property + def column(self) -> int: + return self.parent.indexAt(self.pos()).column() def setBackground(self, color: QColor) -> None: """ @@ -126,6 +132,25 @@ def eventFilter(self, widget: QObject, event: QEvent): return True return QObject.eventFilter(self, widget, event) + def resizeEvent(self, event): + super().resizeEvent(event) + if self.edit_button and self.column == Column.EDIT: + self.edit_button.update_position() + + def enterEvent(self, a0): + super().enterEvent(a0) + if self.column == Column.EDIT: + if not self.edit_button: + self.edit_button = FloatingButtonWidget(parent=self) + self.edit_button.floatingButtonClicked.connect(self._on_create_template) + self.edit_button.update_position() + self.edit_button.show() + + def leaveEvent(self, a0): + super().leaveEvent(a0) + if self.edit_button and self.column == Column.EDIT: + self.edit_button.hide() + def getText(self): return self.toPlainText() @@ -198,3 +223,30 @@ def sizeHint(self) -> QSize: # Prevent extreme height for long text: size = QSize(100, 300) return size + + +if __name__ == '__main__': + import sys + from PyQt5.QtWidgets import QApplication, QTableWidget, QTableWidgetItem + + app = QApplication(sys.argv) + window = QTableWidget() + window.setColumnCount(3) + window.setRowCount(10) + # stretch the last table colum: + window.horizontalHeader().setStretchLastSection(True) + window.setHorizontalHeaderLabels(['CIF', 'Data', 'Edit']) + for row in range(10): + for col in range(3): + window.setCellWidget(row, col, MyQPlainTextEdit(window)) + w = window.cellWidget(row, col) + if col == 2: + w.setText(f'Hello World {random.randint(0, 10000)} {random.randint(0, 10000)}') + w.setMinimumHeight(50) + w.setMinimumWidth(150) + window.resizeRowsToContents() + window.resizeColumnsToContents() + window.show() + window.setMinimumSize(600, 400) + + sys.exit(app.exec_())