Skip to content

Commit

Permalink
ENH: ImageTable integrated with a QSettings file for I/O and state
Browse files Browse the repository at this point in the history
  • Loading branch information
aylward committed May 7, 2024
1 parent 595506a commit 5f74f2b
Show file tree
Hide file tree
Showing 17 changed files with 494 additions and 279 deletions.
Binary file added src/minder3d/icons/scene.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 0 additions & 19 deletions src/minder3d/lib/sovImageTablePanelUtils.py

This file was deleted.

211 changes: 159 additions & 52 deletions src/minder3d/lib/sovImageTablePanelWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
QWidget,
)

from .sovImageTablePanelUtils import get_qthumbnail_from_array
from .sovUtils import get_file_reccords_from_settings, time_and_log
from .sovImageTableSettings import ImageTableSettings
from .sovUtils import time_and_log
from .ui_sovImageTablePanelWidget import Ui_ImageTablePanelWidget


Expand All @@ -30,10 +30,12 @@ def __init__(self, gui, state, parent=None):
self.gui = gui
self.state = state

self.settings = ImageTableSettings()

self.imageTableWidget.setRowCount(0)
self.imageTableWidget.setColumnCount(5)
self.imageTableWidget.setColumnCount(6)
self.imageTableWidget.setHorizontalHeaderLabels(
['Loaded', 'Filename', 'Size', 'Spacing', 'Thumbnail']
['Loaded', 'Type', 'Thumbnail', 'Filename', 'Size', 'Spacing']
)
self.imageTableWidget.setEditTriggers(QTableWidget.NoEditTriggers)
self.imageTableWidget.setSelectionBehavior(QTableWidget.SelectRows)
Expand All @@ -51,15 +53,22 @@ def __init__(self, gui, state, parent=None):
'QTableView{ selection-background-color: rgba(0, 50, 0, 50); }'
)

self.imageTableWidget.cellClicked.connect(self.select_image_by_table)
self.imageTableWidget.cellClicked.connect(self.select_data_by_table)

self.fill_table()

@time_and_log
def update_image(self):
self.fill_table()
self.imageTableWidget.selectRow(self.state.current_image_num)

@time_and_log
def update_scene(self):
self.fill_table()
self.imageTableWidget.selectRow(self.state.current_image_num)

@time_and_log
def redraw_image(self, img_num):
def redraw_image_row(self, row_num):
"""Redraws the image at the specified index in the image table widget.
This function updates the information displayed in the image table
Expand All @@ -74,35 +83,64 @@ def redraw_image(self, img_num):
IndexError: If the specified img_num is out of range.
"""

img_num = row_num
if img_num < len(self.state.image_filename):
self.imageTableWidget.setItem(
row_num, 0, QTableWidgetItem(str('X'))
)
else:
self.imageTableWidget.setItem(row_num, 0, QTableWidgetItem(str('')))
self.imageTableWidget.setItem(
img_num, 0, QTableWidgetItem(str(img_num))
)
qthumb = get_qthumbnail_from_array(
self.state.image_array[img_num][
self.state.image_array[img_num].shape[0] // 2, ::-1, :
]
row_num, 1, QTableWidgetItem(str('Image'))
)
self.imageTableWidget.setItem(
img_num, 1, QTableWidgetItem(QIcon(qthumb), '')
row_num,
2,
QTableWidgetItem(QIcon(self.state.image_thumbnail[img_num]), ''),
)
filename = self.state.image_filename[img_num][-20:]
self.imageTableWidget.setItem(img_num, 2, QTableWidgetItem(filename))
filename = self.state.image_filename[img_num]
self.imageTableWidget.setItem(row_num, 3, QTableWidgetItem(filename))
size_str = [
str(i)
for i in self.state.image[img_num]
.GetLargestPossibleRegion()
.GetSize()
]
self.imageTableWidget.setItem(
img_num, 3, QTableWidgetItem('x'.join(size_str))
row_num, 4, QTableWidgetItem('x'.join(size_str))
)
spacing_str = [
f'{i:.4f}' for i in self.state.image[img_num].GetSpacing()
]
self.imageTableWidget.setItem(
img_num, 4, QTableWidgetItem(', '.join(spacing_str))
row_num, 5, QTableWidgetItem(','.join(spacing_str))
)

@time_and_log
def redraw_scene_row(self, row_num, selected=False):
if selected or (
self.imageTableWidget.item(row_num, 3) is not None
and self.imageTableWidget.item(row_num, 3).text()
== self.state.scene_filename
):
self.imageTableWidget.setItem(
row_num, 0, QTableWidgetItem(str('X'))
)
else:
self.imageTableWidget.setItem(row_num, 0, QTableWidgetItem(str('')))
self.imageTableWidget.setItem(
row_num, 1, QTableWidgetItem(str('Scene'))
)
self.imageTableWidget.setItem(
row_num, 2, QTableWidgetItem(QIcon(self.state.scene_thumbnail), '')
)
self.imageTableWidget.setItem(
row_num, 3, QTableWidgetItem(str(self.state.scene_filename))
)
size = self.state.scene.GetNumberOfChildren()
self.imageTableWidget.setItem(row_num, 4, QTableWidgetItem(str(size)))
self.imageTableWidget.setItem(row_num, 5, QTableWidgetItem(str('')))

@time_and_log
def fill_table(self):
"""Fill the image table with images from the state and from settings.
Expand All @@ -118,54 +156,123 @@ def fill_table(self):
"""

self.imageTableWidget.clear()
for img_num in range(len(self.state.image)):
self.imageTableWidget.insertRow(img_num)
self.redraw_image(img_num)
file_records = get_file_reccords_from_settings()
img_num = self.imageTableWidget.rowCount()
self.imageTableWidget.setRowCount(0)
self.imageTableWidget.setHorizontalHeaderLabels(
['Loaded', 'Type', 'Thumbnail', 'Filename', 'Size', 'Spacing']
)
row_num = 0
for _ in range(len(self.state.image)):
self.imageTableWidget.insertRow(row_num)
self.redraw_image_row(row_num)
row_num += 1
if self.state.scene.GetNumberOfChildren() > 0:
self.imageTableWidget.insertRow(row_num)
self.redraw_scene_row(row_num, selected=True)
row_num += 1

file_records = self.settings.get_file_records()
for file in file_records:
if (
file.filename not in self.state.image_filename
and file.file_type == 'image'
):
self.imageTableWidget.insertRow(img_num)
self.imageTableWidget.insertRow(row_num)
self.imageTableWidget.setItem(
row_num, 1, QTableWidgetItem('Image')
)
if file.file_thumbnail != '':
qthumb = QPixmap(file.file_thumbnail)
self.imageTableWidget.setItem(
row_num, 2, QTableWidgetItem(QIcon(qthumb), '')
)
self.imageTableWidget.setItem(
row_num, 3, QTableWidgetItem(str(file.filename))
)
self.imageTableWidget.setItem(
row_num, 4, QTableWidgetItem(str(file.file_size))
)
self.imageTableWidget.setItem(
row_num, 5, QTableWidgetItem(str(file.file_spacing))
)
row_num += 1
elif (
file.filename != self.state.scene_filename
and file.file_type == 'scene'
):
self.imageTableWidget.insertRow(row_num)
self.imageTableWidget.setItem(
row_num, 1, QTableWidgetItem('Scene')
)
qthumb = QPixmap(file.file_thumbnail)
self.imageTableWidget.setItem(
img_num, 1, QTableWidgetItem(QIcon(qthumb), '')
row_num, 2, QTableWidgetItem(QIcon(qthumb), '')
)
self.imageTableWidget.setItem(
img_num, 2, QTableWidgetItem(file.filename)
row_num, 3, QTableWidgetItem(file.filename)
)
if isinstance(file.file_size, list) and len(file.file_size) > 0:
size_str = [str(i) for i in file.file_size]
self.imageTableWidget.setItem(
img_num, 3, QTableWidgetItem('x'.join(size_str))
)
if (
isinstance(file.file_spacing, list)
and len(file.file_spacing) > 0
):
spacing_str = [f'{i:.4f}' for i in file.file_spacing]
self.imageTableWidget.setItem(
img_num, 4, QTableWidgetItem(', '.join(spacing_str))
)
img_num += 1
self.imageTableWidget.setItem(
row_num, 4, QTableWidgetItem(file.file_size)
)
row_num += 1

@time_and_log
def create_new_image(self):
img_num = self.state.current_image_num
self.imageTableWidget.insertRow(img_num)
self.redraw_image(img_num)
self.state.image_thumbnail.append(
self.settings.get_thumbnail(
self.state.image[-1], self.state.image_filename[-1], 'image'
)
)
self.settings.add_data(
self.state.image[-1],
self.state.image_filename[-1],
'image',
self.state.image_thumbnail[-1],
)
self.fill_table()

def replace_image(self, img_num):
self.redraw_image(img_num)
@time_and_log
def save_image(self, filename):
self.settings.add_data(
self.state.image[self.state.current_image_num],
filename,
'image',
self.state.image_thumbnail[self.state.current_image_num],
)
self.fill_table()

@time_and_log
def load_scene(self):
self.state.scene_thumbnail = self.settings.get_thumbnail(
self.state.scene, self.state.scene_filename, 'scene'
)
self.settings.add_data(
self.state.scene,
self.state.scene_filename,
'scene',
self.state.scene_thumbnail,
)
self.fill_table()

def select_image_by_table(self, row, _):
sel_num = int(self.imageTableWidget.item(row, 0).text())
if self.state.current_image_num == sel_num:
return
@time_and_log
def save_scene(self, filename):
self.settings.add_data(
self.state.scene, filename, 'scene', self.state.scene_thumbnail
)

self.state.current_image_num = sel_num
self.gui.update_image()
@time_and_log
def replace_image(self, img_num):
self.redraw_image_row(img_num)

@time_and_log
def select_data_by_table(self, row, _):
if row < len(self.state.image_filename):
self.state.current_image_num = row
self.gui.update_image()

if self.state.view2D_overlay_auto_update:
self.gui.update_overlay()
if self.state.view2D_overlay_auto_update:
self.gui.update_overlay()
else:
if self.imageTableWidget.item(row, 1).text() == 'Image':
self.gui.load_image(self.imageTableWidget.item(row, 3).text())
elif self.imageTableWidget.item(row, 1).text() == 'Scene':
self.gui.load_scene(self.imageTableWidget.item(row, 3).text())
15 changes: 14 additions & 1 deletion src/minder3d/lib/sovImageTablePanelWidget.ui
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,20 @@
<number>3</number>
</property>
<item>
<widget class="QTableWidget" name="imageTableWidget"/>
<widget class="QTableWidget" name="imageTableWidget">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<attribute name="horizontalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
Expand Down
Loading

0 comments on commit 5f74f2b

Please sign in to comment.