init
This commit is contained in:
0
crystalfly/__init__.py
Normal file
0
crystalfly/__init__.py
Normal file
BIN
crystalfly/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
crystalfly/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
16
crystalfly/main.py
Normal file
16
crystalfly/main.py
Normal file
@ -0,0 +1,16 @@
|
||||
import sys
|
||||
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
from crystalfly.ui.main_window import MainWindow
|
||||
|
||||
|
||||
def main():
|
||||
app = QApplication(sys.argv)
|
||||
window = MainWindow()
|
||||
window.show()
|
||||
app.exec()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
0
crystalfly/model/__init__.py
Normal file
0
crystalfly/model/__init__.py
Normal file
BIN
crystalfly/model/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
crystalfly/model/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
crystalfly/model/__pycache__/image_reader.cpython-311.pyc
Normal file
BIN
crystalfly/model/__pycache__/image_reader.cpython-311.pyc
Normal file
Binary file not shown.
16
crystalfly/model/image_reader.py
Normal file
16
crystalfly/model/image_reader.py
Normal file
@ -0,0 +1,16 @@
|
||||
from typing import Any
|
||||
|
||||
from PySide6.QtCore import QObject, Signal
|
||||
|
||||
|
||||
class ImageReaderModel(QObject):
|
||||
loadedSignal = Signal(Any)
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
def loaded(self, image):
|
||||
self.loadedSignal.emit(image)
|
||||
|
||||
|
||||
image_reader_model = ImageReaderModel()
|
0
crystalfly/thread/__init__.py
Normal file
0
crystalfly/thread/__init__.py
Normal file
BIN
crystalfly/thread/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
crystalfly/thread/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
crystalfly/thread/__pycache__/image_reader.cpython-311.pyc
Normal file
BIN
crystalfly/thread/__pycache__/image_reader.cpython-311.pyc
Normal file
Binary file not shown.
34
crystalfly/thread/image_reader.py
Normal file
34
crystalfly/thread/image_reader.py
Normal file
@ -0,0 +1,34 @@
|
||||
from typing import Any
|
||||
|
||||
from PySide6.QtCore import QThread, Signal
|
||||
from vtkmodules.vtkIOImage import vtkMedicalImageReader2
|
||||
|
||||
from crystalfly.model.image_reader import image_reader_model
|
||||
|
||||
|
||||
class ImageReaderThread(QThread):
|
||||
loadedSignal = Signal(Any)
|
||||
|
||||
def __init__(self, file_data):
|
||||
QThread.__init__(self)
|
||||
self.file_data = file_data
|
||||
|
||||
def run(self):
|
||||
reader = vtkMedicalImageReader2()
|
||||
reader.SetFileName(self.file_data["file_path"])
|
||||
reader.SetFileDimensionality(3)
|
||||
reader.SetDataSpacing(0.1, 0.1, 0.1)
|
||||
print(self.file_data)
|
||||
reader.SetDataExtent(
|
||||
0,
|
||||
self.file_data["size"]["x"] - 1,
|
||||
0,
|
||||
self.file_data["size"]["y"] - 1,
|
||||
0,
|
||||
self.file_data["size"]["z"] - 1,
|
||||
)
|
||||
# self.file_data["data_type"]
|
||||
reader.SetDataScalarTypeToUnsignedShort()
|
||||
reader.Update()
|
||||
image_reader_model.loaded(reader.GetOutput())
|
||||
print("success")
|
0
crystalfly/ui/__init__.py
Normal file
0
crystalfly/ui/__init__.py
Normal file
BIN
crystalfly/ui/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
crystalfly/ui/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
crystalfly/ui/__pycache__/import_file.cpython-311.pyc
Normal file
BIN
crystalfly/ui/__pycache__/import_file.cpython-311.pyc
Normal file
Binary file not shown.
BIN
crystalfly/ui/__pycache__/main_window.cpython-311.pyc
Normal file
BIN
crystalfly/ui/__pycache__/main_window.cpython-311.pyc
Normal file
Binary file not shown.
BIN
crystalfly/ui/__pycache__/vtk_viewer.cpython-311.pyc
Normal file
BIN
crystalfly/ui/__pycache__/vtk_viewer.cpython-311.pyc
Normal file
Binary file not shown.
52
crystalfly/ui/import_file.py
Normal file
52
crystalfly/ui/import_file.py
Normal file
@ -0,0 +1,52 @@
|
||||
from pathlib import Path
|
||||
|
||||
from PySide6.QtCore import Slot, QEvent
|
||||
from PySide6.QtUiTools import loadUiType
|
||||
from PySide6.QtWidgets import QDialog, QFileDialog
|
||||
|
||||
from crystalfly.thread.image_reader import ImageReaderThread
|
||||
|
||||
ImportFileType, _ = loadUiType(str(Path(__file__).parent.joinpath("import_file.ui")))
|
||||
|
||||
|
||||
class ImportFile(QDialog, ImportFileType):
|
||||
def __init__(self):
|
||||
super(ImportFile, self).__init__()
|
||||
self.image_read_thread = None
|
||||
self.setupUi(self)
|
||||
|
||||
self.browse_file.clicked.connect(self.browse_file_handler)
|
||||
self.accepted.connect(self.load_image_file)
|
||||
|
||||
def showEvent(self, event: QEvent) -> None:
|
||||
self.clear_form()
|
||||
|
||||
def clear_form(self):
|
||||
self.file_path_input.clear()
|
||||
self.size_x_spin.clear()
|
||||
self.size_y_spin.clear()
|
||||
self.size_z_spin.clear()
|
||||
self.data_type_combobox.setCurrentIndex(0)
|
||||
|
||||
@Slot()
|
||||
def load_image_file(self):
|
||||
file_data = {
|
||||
"file_path": self.file_path_input.text(),
|
||||
"data_type": self.data_type_combobox.currentText(),
|
||||
"size": {
|
||||
"x": self.size_x_spin.value(),
|
||||
"y": self.size_y_spin.value(),
|
||||
"z": self.size_z_spin.value(),
|
||||
}
|
||||
}
|
||||
self.image_read_thread = ImageReaderThread(file_data)
|
||||
# self.image_read_thread.loadedSignal.connect(self.set_image)
|
||||
self.image_read_thread.start()
|
||||
|
||||
|
||||
@Slot()
|
||||
def browse_file_handler(self):
|
||||
dialog = QFileDialog(self)
|
||||
filepath = dialog.getOpenFileName()
|
||||
if filepath[0]:
|
||||
self.file_path_input.setText(filepath[0])
|
208
crystalfly/ui/import_file.ui
Normal file
208
crystalfly/ui/import_file.ui
Normal file
@ -0,0 +1,208 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog</class>
|
||||
<widget class="QDialog" name="Dialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>500</width>
|
||||
<height>259</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>文件导入</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="1,5,1">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>文件路径</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="file_path_input"/>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="browse_file">
|
||||
<property name="text">
|
||||
<string>浏览</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>size</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="1,3,1,3">
|
||||
<property name="horizontalSpacing">
|
||||
<number>32</number>
|
||||
</property>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>y</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="size_x_spin">
|
||||
<property name="maximum">
|
||||
<number>100000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>x</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QSpinBox" name="size_y_spin">
|
||||
<property name="maximum">
|
||||
<number>100000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>z</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="size_z_spin">
|
||||
<property name="maximum">
|
||||
<number>100000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_3" columnstretch="1,6">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>数据类型</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="data_type_combobox">
|
||||
<property name="editable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>int 8</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>uint 8</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>int 16</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>uint 16</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>int 32</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>uint 32</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>float</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
39
crystalfly/ui/main_window.py
Normal file
39
crystalfly/ui/main_window.py
Normal file
@ -0,0 +1,39 @@
|
||||
from pathlib import Path
|
||||
|
||||
from PySide6.QtCore import Slot
|
||||
from PySide6.QtUiTools import loadUiType
|
||||
from PySide6.QtWidgets import QMainWindow
|
||||
|
||||
from crystalfly.ui.import_file import ImportFile
|
||||
from crystalfly.ui.vtk_viewer import VTKImageViewer
|
||||
|
||||
MainWindowType, _ = loadUiType(str(Path(__file__).parent.joinpath("main_window.ui")))
|
||||
|
||||
|
||||
class MainWindow(QMainWindow, MainWindowType):
|
||||
def __init__(self):
|
||||
super(MainWindow, self).__init__()
|
||||
self.setupUi(self)
|
||||
self.file_open_dialog = ImportFile()
|
||||
self.file_open.triggered.connect(self.handle_file_open)
|
||||
self.init_four_pane()
|
||||
|
||||
def init_four_pane(self):
|
||||
coronal = VTKImageViewer()
|
||||
coronal.image_viewer.SetSliceOrientationToYZ()
|
||||
sagittal = VTKImageViewer()
|
||||
sagittal.image_viewer.SetSliceOrientationToXZ()
|
||||
transverse = VTKImageViewer()
|
||||
transverse.image_viewer.SetSliceOrientationToXY()
|
||||
# self.gridLayout.addWidget()
|
||||
self.gridLayout_2.addWidget(coronal)
|
||||
self.gridLayout_3.addWidget(sagittal)
|
||||
self.gridLayout_4.addWidget(transverse)
|
||||
|
||||
@Slot()
|
||||
def cell_click(self):
|
||||
print("clicked")
|
||||
|
||||
@Slot()
|
||||
def handle_file_open(self):
|
||||
self.file_open_dialog.exec()
|
166
crystalfly/ui/main_window.ui
Normal file
166
crystalfly/ui/main_window.ui
Normal file
@ -0,0 +1,166 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Crystalfly</string>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"># background-color: rgb(50, 50, 50);</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,4">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border-color: rgb(195, 195, 195);</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>工具栏</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="four_pane_grid">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QWidget" name="widget_2" native="true">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border: 1px solid rgb(195, 195, 195);</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QWidget" name="widget_3" native="true">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border: 1px solid rgb(195, 195, 195);
|
||||
margin-left: -1px;</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QWidget" name="widget_5" native="true">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border: 1px solid rgb(195, 195, 195);
|
||||
margin-left: -1px;
|
||||
margin-top: -1px;</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QWidget" name="widget_4" native="true">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">border: 1px solid rgb(195, 195, 195);
|
||||
margin-top: -1px;</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu">
|
||||
<property name="title">
|
||||
<string>文件</string>
|
||||
</property>
|
||||
<addaction name="file_open"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_2">
|
||||
<property name="title">
|
||||
<string>工具</string>
|
||||
</property>
|
||||
</widget>
|
||||
<addaction name="menu"/>
|
||||
<addaction name="menu_2"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<action name="file_open">
|
||||
<property name="text">
|
||||
<string>打开</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
51
crystalfly/ui/vtk_viewer.py
Normal file
51
crystalfly/ui/vtk_viewer.py
Normal file
@ -0,0 +1,51 @@
|
||||
# noinspection PyUnresolvedReferences
|
||||
# import vtkmodules.vtkRenderingContextOpenGL2
|
||||
from PySide6.QtGui import QCloseEvent
|
||||
from vtkmodules.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
|
||||
from vtkmodules.vtkInteractionImage import vtkImageViewer2
|
||||
from vtkmodules.vtkInteractionStyle import vtkInteractorStyleImage
|
||||
|
||||
from crystalfly.model.image_reader import image_reader_model
|
||||
|
||||
|
||||
class VTKImageViewer(QVTKRenderWindowInteractor):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.render_window = self.GetRenderWindow()
|
||||
|
||||
# image viewer
|
||||
self.image_viewer = vtkImageViewer2()
|
||||
# self.image_viewer.SetRenderWindow(self.render_window)
|
||||
|
||||
# 交互
|
||||
self.interactor_style = vtkInteractorStyleImage()
|
||||
self.iren = self.render_window.GetInteractor()
|
||||
self.iren.SetInteractorStyle(self.interactor_style)
|
||||
self.interactor_style.AddObserver("MouseWheelForwardEvent", self.mouse_wheel_forward_event)
|
||||
self.interactor_style.AddObserver("MouseWheelBackwardEvent", self.mouse_wheel_backward_event)
|
||||
self.iren.Initialize()
|
||||
|
||||
image_reader_model.loadedSignal.connect(self.set_image)
|
||||
|
||||
def set_image(self, image):
|
||||
if self.image_viewer.GetRenderWindow() is not None:
|
||||
self.image_viewer.SetRenderWindow(self.render_window)
|
||||
self.image_viewer.SetInputData(image)
|
||||
self.image_viewer.Render()
|
||||
print("setImage")
|
||||
|
||||
def mouse_wheel_forward_event(self, a, b):
|
||||
if self.image_viewer.GetSlice() < self.image_viewer.GetSliceMax():
|
||||
print(self.image_viewer.GetSlice())
|
||||
self.image_viewer.SetSlice(self.image_viewer.GetSlice() + 1)
|
||||
self.image_viewer.Render()
|
||||
|
||||
def mouse_wheel_backward_event(self, a, b):
|
||||
if self.image_viewer.GetSlice() > self.image_viewer.GetSliceMin():
|
||||
print(self.image_viewer.GetSlice())
|
||||
self.image_viewer.SetSlice(self.image_viewer.GetSlice() - 1)
|
||||
self.image_viewer.Render()
|
||||
|
||||
def closeEvent(self, evt: QCloseEvent):
|
||||
super().closeEvent(evt)
|
||||
self.Finalize()
|
Reference in New Issue
Block a user