i18n and ini-file
added internationalization, clsTableWidget and INI-file settings and pyinstaller-scripts
This commit is contained in:
parent
90afe07406
commit
48f8dc221a
20 changed files with 1230 additions and 333 deletions
258
src/clsTableWidget.py
Normal file
258
src/clsTableWidget.py
Normal file
|
@ -0,0 +1,258 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
project: clsTableWidget
|
||||
file: clsTableWidget.py
|
||||
summary: Implements my own TableWidget class
|
||||
author: Paul Salajean (p.salajean[at]gmx.de)
|
||||
license: GPL
|
||||
version: 0.1
|
||||
"""
|
||||
|
||||
# Standard library imports
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Third party imports
|
||||
from PySide2.QtWidgets import QApplication, QTableWidget, QAbstractItemView, QTableWidgetItem, QMenu, \
|
||||
QMainWindow, QMessageBox
|
||||
from PySide2.QtCore import Qt, QItemSelectionModel, QCoreApplication
|
||||
from PySide2.QtGui import QIcon
|
||||
|
||||
# local globals
|
||||
SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
ICON_CLEAR = SCRIPT_PATH + "./img/icons8-clear-symbol-16.png"
|
||||
ICON_COPY = SCRIPT_PATH + "./img/icons8-copy-16.png"
|
||||
ICON_ERASER = SCRIPT_PATH + "/img/icons8-eraser-16.png"
|
||||
ICON_INSERT = SCRIPT_PATH + "/img/icons8-insert-clip-16.png"
|
||||
ICON_APPEND = SCRIPT_PATH + "/img/icons8-append-clip-16.png"
|
||||
ICON_PASTE = SCRIPT_PATH + "/img/icons8-paste-16.png"
|
||||
ICON_CUT = SCRIPT_PATH + "/img/icons8-scissors-16.png"
|
||||
ICON_ADD_ROW = SCRIPT_PATH + "/img/icons8-add-row-16.png"
|
||||
ICON_DEL = SCRIPT_PATH + "/img/icons8-delete-16.png"
|
||||
|
||||
# def resource_path(relative_path):
|
||||
# """ Get absolute path to resource, works for dev and for PyInstaller """
|
||||
# try:
|
||||
# # PyInstaller creates a temp folder and stores path in _MEIPASS
|
||||
# base_path = sys._MEIPASS
|
||||
# print("base_path", base_path)
|
||||
# except Exception:
|
||||
# base_path = os.path.abspath(".")
|
||||
|
||||
# return os.path.join(base_path, relative_path)
|
||||
|
||||
class TableWidget(QTableWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__()
|
||||
|
||||
self.parent = parent
|
||||
self.setParent(parent)
|
||||
|
||||
# self.setSelectionMode(QAbstractItemView.ContiguousSelection)
|
||||
self.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||
|
||||
self.setSelectionBehavior(QTableWidget.SelectItems)
|
||||
#self.setSelectionBehavior(QTableWidget.SelectRows)
|
||||
self.setAlternatingRowColors(True)
|
||||
|
||||
# Context-menu
|
||||
self.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||
self.customContextMenuRequested.connect(self.on_context_menu)
|
||||
|
||||
# self.setEditTriggers(QAbstractItemView.DoubleClicked | QAbstractItemView.EditKeyPressed | QAbstractItemView.AnyKeyPressed)
|
||||
|
||||
self.headers = self.verticalHeader()
|
||||
self.headers.setContextMenuPolicy(Qt.CustomContextMenu)
|
||||
self.headers.customContextMenuRequested.connect(self.on_rowheadercontext_menu)
|
||||
self.headers.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||
self.headers.sectionClicked.connect(self.select_row)
|
||||
|
||||
self.row_selected = False
|
||||
|
||||
def select_row(self, row):
|
||||
self.setSelectionBehavior(QTableWidget.SelectRows)
|
||||
self.selectRow(row)
|
||||
self.setSelectionBehavior(QTableWidget.SelectItems)
|
||||
self.row_selected = True
|
||||
|
||||
def on_context_menu(self, position):
|
||||
menu = QMenu()
|
||||
item_cut = menu.addAction(QIcon(ICON_CUT), QCoreApplication.translate("TableWidget", "Cut") + "\tCtrl+X")
|
||||
item_copy = menu.addAction(QIcon(ICON_COPY), QCoreApplication.translate("TableWidget", "Copy") + "\tCtrl+C")
|
||||
item_paste = menu.addAction(QIcon(ICON_PASTE), QCoreApplication.translate("TableWidget", "Paste") + "\tCtrl+V")
|
||||
menu.addSeparator()
|
||||
|
||||
print(ICON_ERASER)
|
||||
item_delete = menu.addAction(QIcon(ICON_ERASER), QCoreApplication.translate("TableWidget", "Delete") + "\tDel")
|
||||
|
||||
ac = menu.exec_(self.mapToGlobal(position))
|
||||
|
||||
if ac == item_cut:
|
||||
self.item_cut()
|
||||
elif ac == item_copy:
|
||||
self.item_copy()
|
||||
elif ac == item_paste:
|
||||
self.item_paste()
|
||||
elif ac == item_delete:
|
||||
self.item_del()
|
||||
|
||||
def on_rowheadercontext_menu(self, position):
|
||||
menu = QMenu()
|
||||
row_cut = menu.addAction(QIcon(ICON_CUT), QCoreApplication.translate("TableWidget", "Cut row"))
|
||||
row_copy = menu.addAction(QIcon(ICON_COPY), QCoreApplication.translate("TableWidget", "Copy row"))
|
||||
row_paste = menu.addAction(QIcon(ICON_PASTE), QCoreApplication.translate("TableWidget", "Paste row"))
|
||||
menu.addSeparator()
|
||||
row_insert_before = menu.addAction(QIcon(ICON_INSERT), QCoreApplication.translate("TableWidget", "Insert row before"))
|
||||
row_insert_after = menu.addAction(QIcon(ICON_APPEND), QCoreApplication.translate("TableWidget", "Insert row after"))
|
||||
menu.addSeparator()
|
||||
row_remove = menu.addAction(QIcon(ICON_DEL), QCoreApplication.translate("TableWidget", "Remove row"))
|
||||
row_delete_items = menu.addAction(QIcon(ICON_ERASER), QCoreApplication.translate("TableWidget", "Delete items"))
|
||||
ac = menu.exec_(self.mapToGlobal(position))
|
||||
|
||||
row = self.headers.logicalIndexAt(position)
|
||||
|
||||
if ac == row_cut:
|
||||
self.item_cut()
|
||||
elif ac == row_copy:
|
||||
self.item_copy()
|
||||
elif ac == row_paste:
|
||||
self.item_paste()
|
||||
elif ac == row_insert_before:
|
||||
self.row_insert(row)
|
||||
elif ac == row_insert_after:
|
||||
self.row_insert(row+1)
|
||||
elif ac == row_remove:
|
||||
self.row_remove(row)
|
||||
elif ac == row_delete_items:
|
||||
self.row_delete_items()
|
||||
|
||||
def row_insert(self, row):
|
||||
self.insertRow(row)
|
||||
|
||||
def has_data(self, row):
|
||||
""" Check if target already contains data. """
|
||||
# sel_idx = self.selectionModel().selectedIndexes()
|
||||
for col in range(self.columnCount()):
|
||||
item = self.item(row, col)
|
||||
if item:
|
||||
if len(item.text()) > 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
def row_remove(self, row):
|
||||
if self.has_data(row):
|
||||
msg = QCoreApplication.translate("TableWidget", "Row Nr.") + " " + str(row+1) + " " + QCoreApplication.translate("TableWidget", "to be removed?")
|
||||
reply = QMessageBox.question(self, QCoreApplication.translate("TableWidget", "Remove"), msg, \
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
|
||||
if reply == QMessageBox.No:
|
||||
return False
|
||||
|
||||
self.removeRow(row)
|
||||
return True
|
||||
|
||||
def row_delete_items(self):
|
||||
self.item_del()
|
||||
|
||||
def keyPressEvent(self, event):
|
||||
super().keyPressEvent(event)
|
||||
modifiers = QApplication.keyboardModifiers()
|
||||
|
||||
key = event.key()
|
||||
|
||||
if modifiers == Qt.ControlModifier:
|
||||
if key == Qt.Key_C:
|
||||
self.item_copy()
|
||||
|
||||
elif key == Qt.Key_V:
|
||||
self.item_paste()
|
||||
|
||||
elif key == Qt.Key_X:
|
||||
self.item_cut()
|
||||
|
||||
elif key == Qt.Key_A:
|
||||
self.setSelectionMode(QAbstractItemView.ContiguousSelection)
|
||||
self.selectAll()
|
||||
self.setSelectionMode(QAbstractItemView.SingleSelection)
|
||||
|
||||
if key == Qt.Key_Delete:
|
||||
self.item_del()
|
||||
|
||||
elif key == Qt.Key_Escape:
|
||||
self.clearSelection()
|
||||
|
||||
def item_paste(self):
|
||||
cur_row = self.currentRow()
|
||||
cur_col = self.currentColumn()
|
||||
# ask_confirmation = True
|
||||
|
||||
if self.row_selected:
|
||||
cur_col = 0
|
||||
|
||||
col = 0
|
||||
if len(self.clipboard_data) == 1:
|
||||
data = self.clipboard_data[0]
|
||||
item = QTableWidgetItem(data)
|
||||
|
||||
self.setItem(cur_row, cur_col, item)
|
||||
item.setSelected(True)
|
||||
else:
|
||||
for data in self.clipboard_data:
|
||||
item = QTableWidgetItem(data)
|
||||
# if item:
|
||||
# if len(item.text()) >0:
|
||||
# if ask_confirmation:
|
||||
# msg = QCoreApplication.translate("TableWidget", "Zelle enthält bereits Daten. Überschreiben?")
|
||||
# reply = QMessageBox.question(self, QCoreApplication.translate("TableWidget", "Überschreiben"), msg, \
|
||||
# QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
|
||||
# if reply == QMessageBox.No:
|
||||
# return False
|
||||
|
||||
# ask_confirmation = False
|
||||
self.setItem(cur_row, col, item)
|
||||
item.setSelected(True)
|
||||
|
||||
col += 1
|
||||
|
||||
def item_cut(self):
|
||||
self.item_copy()
|
||||
|
||||
sel_idx = self.selectedIndexes()
|
||||
|
||||
for idx in sel_idx:
|
||||
item = self.itemFromIndex(idx)
|
||||
try:
|
||||
item.setData(Qt.DisplayRole, None)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def item_copy(self):
|
||||
sel_idx = self.selectedIndexes()
|
||||
sel_rows = self.selectionModel().selectedRows()
|
||||
|
||||
if len(sel_idx) == 1:
|
||||
self.row_selected = False
|
||||
|
||||
self.sel_ranges = self.selectedRanges()
|
||||
|
||||
self.clipboard_data = []
|
||||
for idx in sel_idx:
|
||||
self.clipboard_data.append(idx.data())
|
||||
|
||||
def item_del(self):
|
||||
ask_cofirmation = True
|
||||
sel_idx = self.selectionModel().selectedIndexes()
|
||||
for idx in sel_idx:
|
||||
row = idx.row()
|
||||
col = idx.column()
|
||||
item = self.item(row, col)
|
||||
if item:
|
||||
if self.has_data(row) and ask_cofirmation:
|
||||
msg = QCoreApplication.translate("TableWidget", "Delete cell content?")
|
||||
reply = QMessageBox.question(self, QCoreApplication.translate("TableWidget", "Delete"), msg, \
|
||||
QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
|
||||
if reply == QMessageBox.No:
|
||||
return False
|
||||
|
||||
ask_cofirmation = False
|
||||
item.setData(Qt.DisplayRole, None)
|
Loading…
Add table
Add a link
Reference in a new issue