mirror of
https://github.com/k4yt3x/video2x.git
synced 2025-03-03 21:12:13 +00:00
upgraded input QLineEdit to QTableView
This commit is contained in:
parent
d12f2a3888
commit
f2943802cb
@ -4,7 +4,7 @@
|
||||
Name: Video2X Upscaler
|
||||
Author: K4YT3X
|
||||
Date Created: December 10, 2018
|
||||
Last Modified: May 7, 2020
|
||||
Last Modified: May 8, 2020
|
||||
|
||||
Description: This file contains the Upscaler class. Each
|
||||
instance of the Upscaler class is an upscaler on an image or
|
||||
@ -30,9 +30,7 @@ import queue
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
import traceback
|
||||
|
||||
@ -71,8 +69,8 @@ class Upscaler:
|
||||
|
||||
def __init__(self, input_path, output_path, driver_settings, ffmpeg_settings):
|
||||
# mandatory arguments
|
||||
self.input_path = input_path
|
||||
self.output_path = output_path
|
||||
self.input = input_path
|
||||
self.output = output_path
|
||||
self.driver_settings = driver_settings
|
||||
self.ffmpeg_settings = ffmpeg_settings
|
||||
|
||||
@ -134,20 +132,30 @@ class Upscaler:
|
||||
traceback.print_exc()
|
||||
|
||||
def _check_arguments(self):
|
||||
if isinstance(self.input, list):
|
||||
if self.output.exists() and not self.output.is_dir():
|
||||
Avalon.error(_('Input and output path type mismatch'))
|
||||
Avalon.error(_('Input is multiple files but output is not directory'))
|
||||
raise ArgumentError('input output path type mismatch')
|
||||
for input_path in self.input:
|
||||
if not input_path.is_file() and not input_path.is_dir():
|
||||
Avalon.error(_('Input path {} is neither a file nor a directory'.format(input_path)))
|
||||
raise FileNotFoundError(f'{input_path} is neither file nor directory')
|
||||
|
||||
# if input is a file
|
||||
if self.input_path.is_file():
|
||||
if self.output_path.is_dir():
|
||||
elif self.input.is_file():
|
||||
if self.output.is_dir():
|
||||
Avalon.error(_('Input and output path type mismatch'))
|
||||
Avalon.error(_('Input is single file but output is directory'))
|
||||
raise ArgumentError('input output path type mismatch')
|
||||
if not re.search(r'.*\..*$', str(self.output_path)):
|
||||
if not re.search(r'.*\..*$', str(self.output)):
|
||||
Avalon.error(_('No suffix found in output file path'))
|
||||
Avalon.error(_('Suffix must be specified for FFmpeg'))
|
||||
raise ArgumentError('no output video suffix specified')
|
||||
|
||||
# if input is a directory
|
||||
elif self.input_path.is_dir():
|
||||
if self.output_path.is_file():
|
||||
elif self.input.is_dir():
|
||||
if self.output.is_file():
|
||||
Avalon.error(_('Input and output path type mismatch'))
|
||||
Avalon.error(_('Input is directory but output is existing single file'))
|
||||
raise ArgumentError('input output path type mismatch')
|
||||
@ -155,7 +163,7 @@ class Upscaler:
|
||||
# if input is neither
|
||||
else:
|
||||
Avalon.error(_('Input path is neither a file nor a directory'))
|
||||
raise FileNotFoundError(f'{self.input_path} is neither file nor directory')
|
||||
raise FileNotFoundError(f'{self.input} is neither file nor directory')
|
||||
|
||||
# check Fmpeg settings
|
||||
ffmpeg_path = pathlib.Path(self.ffmpeg_settings['ffmpeg_path'])
|
||||
@ -390,18 +398,34 @@ class Upscaler:
|
||||
# define processing queue
|
||||
processing_queue = queue.Queue()
|
||||
|
||||
# if input is a list of files
|
||||
if isinstance(self.input, list):
|
||||
# make output directory if it doesn't exist
|
||||
self.output.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for input_path in self.input:
|
||||
|
||||
if input_path.is_file():
|
||||
output_video = self.output / input_path.name
|
||||
processing_queue.put((input_path.absolute(), output_video.absolute()))
|
||||
|
||||
elif input_path.is_dir():
|
||||
for input_video in [f for f in input_path.iterdir() if f.is_file()]:
|
||||
output_video = self.output / input_video.name
|
||||
processing_queue.put((input_video.absolute(), output_video.absolute()))
|
||||
|
||||
# if input specified is single file
|
||||
if self.input_path.is_file():
|
||||
Avalon.info(_('Upscaling single video file: {}').format(self.input_path))
|
||||
processing_queue.put((self.input_path.absolute(), self.output_path.absolute()))
|
||||
elif self.input.is_file():
|
||||
Avalon.info(_('Upscaling single video file: {}').format(self.input))
|
||||
processing_queue.put((self.input.absolute(), self.output.absolute()))
|
||||
|
||||
# if input specified is a directory
|
||||
elif self.input_path.is_dir():
|
||||
elif self.input.is_dir():
|
||||
|
||||
# make output directory if it doesn't exist
|
||||
self.output_path.mkdir(parents=True, exist_ok=True)
|
||||
for input_video in [f for f in self.input_path.iterdir() if f.is_file()]:
|
||||
output_video = self.output_path / input_video.name
|
||||
self.output.mkdir(parents=True, exist_ok=True)
|
||||
for input_video in [f for f in self.input.iterdir() if f.is_file()]:
|
||||
output_video = self.output / input_video.name
|
||||
processing_queue.put((input_video.absolute(), output_video.absolute()))
|
||||
|
||||
while not processing_queue.empty():
|
||||
|
@ -4,7 +4,7 @@
|
||||
Creator: Video2X GUI
|
||||
Author: K4YT3X
|
||||
Date Created: May 5, 2020
|
||||
Last Modified: May 7, 2020
|
||||
Last Modified: May 8, 2020
|
||||
"""
|
||||
|
||||
# local imports
|
||||
@ -14,7 +14,6 @@ from upscaler import Upscaler
|
||||
import contextlib
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
@ -22,9 +21,10 @@ import traceback
|
||||
import yaml
|
||||
|
||||
# third-party imports
|
||||
from PyQt5 import QtWidgets, QtGui
|
||||
from PyQt5 import uic
|
||||
from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal, QRunnable, QThreadPool
|
||||
from PyQt5 import QtGui, uic
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtWidgets import *
|
||||
# QObject, pyqtSlot, pyqtSignal, QRunnable, QThreadPool, QAbstractTableModel, Qt
|
||||
|
||||
VERSION = '2.0.0'
|
||||
|
||||
@ -42,6 +42,7 @@ AVAILABLE_DRIVERS = {
|
||||
'Anime4KCPP': 'anime4kcpp'
|
||||
}
|
||||
|
||||
|
||||
def resource_path(relative_path: str) -> pathlib.Path:
|
||||
try:
|
||||
base_path = pathlib.Path(sys._MEIPASS)
|
||||
@ -56,6 +57,7 @@ class WorkerSignals(QObject):
|
||||
interrupted = pyqtSignal()
|
||||
finished = pyqtSignal()
|
||||
|
||||
|
||||
class ProgressBarWorker(QRunnable):
|
||||
def __init__(self, fn, *args, **kwargs):
|
||||
super(ProgressBarWorker, self).__init__()
|
||||
@ -72,6 +74,7 @@ class ProgressBarWorker(QRunnable):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
class UpscalerWorker(QRunnable):
|
||||
|
||||
def __init__(self, fn, *args, **kwargs):
|
||||
@ -99,7 +102,50 @@ class UpscalerWorker(QRunnable):
|
||||
self.signals.finished.emit()
|
||||
|
||||
|
||||
class Video2XMainWindow(QtWidgets.QMainWindow):
|
||||
class InputTableModel(QAbstractTableModel):
|
||||
def __init__(self, data):
|
||||
super(InputTableModel, self).__init__()
|
||||
self._data = data
|
||||
|
||||
def data(self, index, role):
|
||||
if role == Qt.DisplayRole:
|
||||
|
||||
if index.column() == 0:
|
||||
return str(self._data[index.row()].absolute())
|
||||
else:
|
||||
if self._data[index.row()].is_file():
|
||||
return 'File'
|
||||
elif self._data[index.row()].is_dir():
|
||||
return 'Folder'
|
||||
else:
|
||||
return 'Unknown'
|
||||
|
||||
def rowCount(self, index):
|
||||
return len(self._data)
|
||||
|
||||
def columnCount(self, index):
|
||||
return 2
|
||||
|
||||
def removeRow(self, index):
|
||||
self._data.pop(index)
|
||||
|
||||
def headerData(self, section, orientation, role):
|
||||
# section is the index of the column/row.
|
||||
if role != Qt.DisplayRole:
|
||||
return None
|
||||
|
||||
horizontal_headers = ['File Path', 'Type']
|
||||
|
||||
# return the correspondign header
|
||||
if orientation == Qt.Horizontal:
|
||||
return horizontal_headers[section]
|
||||
|
||||
# simply return the line number
|
||||
if orientation == Qt.Vertical:
|
||||
return str(section)
|
||||
|
||||
|
||||
class Video2XMainWindow(QMainWindow):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@ -114,131 +160,147 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
||||
self.setWindowIcon(QtGui.QIcon(self.video2x_icon_path))
|
||||
|
||||
# menu bar
|
||||
self.action_exit = self.findChild(QtWidgets.QAction, 'actionExit')
|
||||
self.action_exit = self.findChild(QAction, 'actionExit')
|
||||
self.action_exit.triggered.connect(sys.exit)
|
||||
|
||||
self.action_about = self.findChild(QtWidgets.QAction, 'actionAbout')
|
||||
self.action_about = self.findChild(QAction, 'actionAbout')
|
||||
self.action_about.triggered.connect(lambda: self.show_message(LEGAL_INFO, custom_icon=QtGui.QPixmap(self.video2x_icon_path)))
|
||||
|
||||
# main tab
|
||||
# select input file/folder
|
||||
self.input_line_edit = self.findChild(QtWidgets.QLineEdit, 'inputLineEdit')
|
||||
self.enable_line_edit_file_drop(self.input_line_edit)
|
||||
self.input_select_file_button = self.findChild(QtWidgets.QPushButton, 'inputSelectFileButton')
|
||||
self.input_select_file_button.clicked.connect(self.select_input_file)
|
||||
self.input_select_folder_button = self.findChild(QtWidgets.QPushButton, 'inputSelectFolderButton')
|
||||
self.input_select_folder_button.clicked.connect(self.select_input_folder)
|
||||
self.input_table_view = self.findChild(QTableView, 'inputTableView')
|
||||
self.input_table_view.dragEnterEvent = self.dragEnterEvent
|
||||
self.input_table_view.dropEvent = self.dropEvent
|
||||
|
||||
# initialize data in table
|
||||
self.input_table_data = []
|
||||
self.input_table_model = InputTableModel(self.input_table_data)
|
||||
self.input_table_view.setModel(self.input_table_model)
|
||||
# stretch file path and fill columns horizontally
|
||||
self.input_table_view.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
|
||||
|
||||
# input table buttons
|
||||
self.input_select_file_button = self.findChild(QPushButton, 'inputSelectFileButton')
|
||||
self.input_select_file_button.clicked.connect(self.select_input_file)
|
||||
self.input_select_folder_button = self.findChild(QPushButton, 'inputSelectFolderButton')
|
||||
self.input_select_folder_button.clicked.connect(self.select_input_folder)
|
||||
self.input_delete_selected_button = self.findChild(QPushButton, 'inputDeleteSelectedButton')
|
||||
self.input_delete_selected_button.clicked.connect(self.input_table_delete_selected)
|
||||
self.input_clear_all_button = self.findChild(QPushButton, 'inputClearAllButton')
|
||||
self.input_clear_all_button.clicked.connect(self.input_table_clear_all)
|
||||
|
||||
# other paths selection
|
||||
# select output file/folder
|
||||
self.output_line_edit = self.findChild(QtWidgets.QLineEdit, 'outputLineEdit')
|
||||
self.output_line_edit = self.findChild(QLineEdit, 'outputLineEdit')
|
||||
self.enable_line_edit_file_drop(self.output_line_edit)
|
||||
self.output_select_file_button = self.findChild(QtWidgets.QPushButton, 'outputSelectFileButton')
|
||||
self.output_line_edit.setText(str((pathlib.Path().cwd() / 'output').absolute()))
|
||||
self.output_select_file_button = self.findChild(QPushButton, 'outputSelectFileButton')
|
||||
self.output_select_file_button.clicked.connect(self.select_output_file)
|
||||
self.output_select_folder_button = self.findChild(QtWidgets.QPushButton, 'outputSelectFolderButton')
|
||||
self.output_select_folder_button = self.findChild(QPushButton, 'outputSelectFolderButton')
|
||||
self.output_select_folder_button.clicked.connect(self.select_output_folder)
|
||||
|
||||
# config file
|
||||
self.config_line_edit = self.findChild(QtWidgets.QLineEdit, 'configLineEdit')
|
||||
self.config_line_edit = self.findChild(QLineEdit, 'configLineEdit')
|
||||
self.enable_line_edit_file_drop(self.config_line_edit)
|
||||
self.config_line_edit.setText(str((pathlib.Path(__file__).parent / 'video2x.yaml').absolute()))
|
||||
self.config_select_file_button = self.findChild(QtWidgets.QPushButton, 'configSelectButton')
|
||||
self.config_select_file_button = self.findChild(QPushButton, 'configSelectButton')
|
||||
self.config_select_file_button.clicked.connect(self.select_config_file)
|
||||
|
||||
# cache directory
|
||||
self.cache_line_edit = self.findChild(QtWidgets.QLineEdit, 'cacheLineEdit')
|
||||
self.cache_line_edit = self.findChild(QLineEdit, 'cacheLineEdit')
|
||||
self.enable_line_edit_file_drop(self.cache_line_edit)
|
||||
self.cache_select_folder_button = self.findChild(QtWidgets.QPushButton, 'cacheSelectFolderButton')
|
||||
self.cache_select_folder_button = self.findChild(QPushButton, 'cacheSelectFolderButton')
|
||||
self.cache_select_folder_button.clicked.connect(self.select_cache_folder)
|
||||
|
||||
# express settings
|
||||
self.driver_combo_box = self.findChild(QtWidgets.QComboBox, 'driverComboBox')
|
||||
self.driver_combo_box = self.findChild(QComboBox, 'driverComboBox')
|
||||
self.driver_combo_box.currentTextChanged.connect(self.update_gui_for_driver)
|
||||
self.processes_spin_box = self.findChild(QtWidgets.QSpinBox, 'processesSpinBox')
|
||||
self.scale_ratio_double_spin_box = self.findChild(QtWidgets.QDoubleSpinBox, 'scaleRatioDoubleSpinBox')
|
||||
self.preserve_frames_check_box = self.findChild(QtWidgets.QCheckBox, 'preserveFramesCheckBox')
|
||||
self.processes_spin_box = self.findChild(QSpinBox, 'processesSpinBox')
|
||||
self.scale_ratio_double_spin_box = self.findChild(QDoubleSpinBox, 'scaleRatioDoubleSpinBox')
|
||||
self.preserve_frames_check_box = self.findChild(QCheckBox, 'preserveFramesCheckBox')
|
||||
|
||||
# progress bar and start/stop controls
|
||||
self.progress_bar = self.findChild(QtWidgets.QProgressBar, 'progressBar')
|
||||
self.time_elapsed_label = self.findChild(QtWidgets.QLabel, 'timeElapsedLabel')
|
||||
self.time_remaining_label = self.findChild(QtWidgets.QLabel, 'timeRemainingLabel')
|
||||
self.rate_label = self.findChild(QtWidgets.QLabel, 'rateLabel')
|
||||
self.start_button = self.findChild(QtWidgets.QPushButton, 'startButton')
|
||||
self.progress_bar = self.findChild(QProgressBar, 'progressBar')
|
||||
self.time_elapsed_label = self.findChild(QLabel, 'timeElapsedLabel')
|
||||
self.time_remaining_label = self.findChild(QLabel, 'timeRemainingLabel')
|
||||
self.rate_label = self.findChild(QLabel, 'rateLabel')
|
||||
self.start_button = self.findChild(QPushButton, 'startButton')
|
||||
self.start_button.clicked.connect(self.start)
|
||||
self.stop_button = self.findChild(QtWidgets.QPushButton, 'stopButton')
|
||||
self.stop_button = self.findChild(QPushButton, 'stopButton')
|
||||
self.stop_button.clicked.connect(self.stop)
|
||||
|
||||
# driver settings
|
||||
# waifu2x-caffe
|
||||
self.waifu2x_caffe_path_line_edit = self.findChild(QtWidgets.QLineEdit, 'waifu2xCaffePathLineEdit')
|
||||
self.waifu2x_caffe_path_line_edit = self.findChild(QLineEdit, 'waifu2xCaffePathLineEdit')
|
||||
self.enable_line_edit_file_drop(self.waifu2x_caffe_path_line_edit)
|
||||
self.waifu2x_caffe_path_select_button = self.findChild(QtWidgets.QPushButton, 'waifu2xCaffePathSelectButton')
|
||||
self.waifu2x_caffe_path_select_button = self.findChild(QPushButton, 'waifu2xCaffePathSelectButton')
|
||||
self.waifu2x_caffe_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_caffe_path_line_edit))
|
||||
self.waifu2x_caffe_mode_combo_box = self.findChild(QtWidgets.QComboBox, 'waifu2xCaffeModeComboBox')
|
||||
self.waifu2x_caffe_noise_level_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xCaffeNoiseLevelSpinBox')
|
||||
self.waifu2x_caffe_process_combo_box = self.findChild(QtWidgets.QComboBox, 'waifu2xCaffeProcessComboBox')
|
||||
self.waifu2x_caffe_model_combobox = self.findChild(QtWidgets.QComboBox, 'waifu2xCaffeModelComboBox')
|
||||
self.waifu2x_caffe_crop_size_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xCaffeCropSizeSpinBox')
|
||||
self.waifu2x_caffe_output_quality_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xCaffeOutputQualitySpinBox')
|
||||
self.waifu2x_caffe_output_depth_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xCaffeOutputDepthSpinBox')
|
||||
self.waifu2x_caffe_batch_size_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xCaffeBatchSizeSpinBox')
|
||||
self.waifu2x_caffe_gpu_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xCaffeGpuSpinBox')
|
||||
self.waifu2x_caffe_tta_check_box = self.findChild(QtWidgets.QCheckBox, 'waifu2xCaffeTtaCheckBox')
|
||||
self.waifu2x_caffe_mode_combo_box = self.findChild(QComboBox, 'waifu2xCaffeModeComboBox')
|
||||
self.waifu2x_caffe_noise_level_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeNoiseLevelSpinBox')
|
||||
self.waifu2x_caffe_process_combo_box = self.findChild(QComboBox, 'waifu2xCaffeProcessComboBox')
|
||||
self.waifu2x_caffe_model_combobox = self.findChild(QComboBox, 'waifu2xCaffeModelComboBox')
|
||||
self.waifu2x_caffe_crop_size_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeCropSizeSpinBox')
|
||||
self.waifu2x_caffe_output_quality_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeOutputQualitySpinBox')
|
||||
self.waifu2x_caffe_output_depth_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeOutputDepthSpinBox')
|
||||
self.waifu2x_caffe_batch_size_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeBatchSizeSpinBox')
|
||||
self.waifu2x_caffe_gpu_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeGpuSpinBox')
|
||||
self.waifu2x_caffe_tta_check_box = self.findChild(QCheckBox, 'waifu2xCaffeTtaCheckBox')
|
||||
|
||||
# waifu2x-converter-cpp
|
||||
self.waifu2x_converter_cpp_path_line_edit = self.findChild(QtWidgets.QLineEdit, 'waifu2xConverterCppPathLineEdit')
|
||||
self.waifu2x_converter_cpp_path_line_edit = self.findChild(QLineEdit, 'waifu2xConverterCppPathLineEdit')
|
||||
self.enable_line_edit_file_drop(self.waifu2x_converter_cpp_path_line_edit)
|
||||
self.waifu2x_converter_cpp_path_edit_button = self.findChild(QtWidgets.QPushButton, 'waifu2xConverterCppPathSelectButton')
|
||||
self.waifu2x_converter_cpp_path_edit_button = self.findChild(QPushButton, 'waifu2xConverterCppPathSelectButton')
|
||||
self.waifu2x_converter_cpp_path_edit_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_converter_cpp_path_line_edit))
|
||||
self.waifu2x_converter_cpp_png_compression_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xConverterCppPngCompressionSpinBox')
|
||||
self.waifu2x_converter_cpp_processor_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xConverterCppProcessorSpinBox')
|
||||
self.waifu2x_converter_cpp_model_combo_box = self.findChild(QtWidgets.QComboBox, 'waifu2xConverterCppModelComboBox')
|
||||
self.waifu2x_converter_cpp_mode_combo_box = self.findChild(QtWidgets.QComboBox, 'waifu2xConverterCppModeComboBox')
|
||||
self.waifu2x_converter_cpp_disable_gpu_check_box = self.findChild(QtWidgets.QCheckBox, 'disableGpuCheckBox')
|
||||
self.waifu2x_converter_cpp_tta_check_box = self.findChild(QtWidgets.QCheckBox, 'ttaCheckBox')
|
||||
self.waifu2x_converter_cpp_png_compression_spin_box = self.findChild(QSpinBox, 'waifu2xConverterCppPngCompressionSpinBox')
|
||||
self.waifu2x_converter_cpp_processor_spin_box = self.findChild(QSpinBox, 'waifu2xConverterCppProcessorSpinBox')
|
||||
self.waifu2x_converter_cpp_model_combo_box = self.findChild(QComboBox, 'waifu2xConverterCppModelComboBox')
|
||||
self.waifu2x_converter_cpp_mode_combo_box = self.findChild(QComboBox, 'waifu2xConverterCppModeComboBox')
|
||||
self.waifu2x_converter_cpp_disable_gpu_check_box = self.findChild(QCheckBox, 'disableGpuCheckBox')
|
||||
self.waifu2x_converter_cpp_tta_check_box = self.findChild(QCheckBox, 'ttaCheckBox')
|
||||
|
||||
# waifu2x-ncnn-vulkan
|
||||
self.waifu2x_ncnn_vulkan_path_line_edit = self.findChild(QtWidgets.QLineEdit, 'waifu2xNcnnVulkanPathLineEdit')
|
||||
self.waifu2x_ncnn_vulkan_path_line_edit = self.findChild(QLineEdit, 'waifu2xNcnnVulkanPathLineEdit')
|
||||
self.enable_line_edit_file_drop(self.waifu2x_ncnn_vulkan_path_line_edit)
|
||||
self.waifu2x_ncnn_vulkan_path_select_button = self.findChild(QtWidgets.QPushButton, 'waifu2xNcnnVulkanPathSelectButton')
|
||||
self.waifu2x_ncnn_vulkan_path_select_button = self.findChild(QPushButton, 'waifu2xNcnnVulkanPathSelectButton')
|
||||
self.waifu2x_ncnn_vulkan_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_ncnn_vulkan_path_line_edit))
|
||||
self.waifu2x_ncnn_vulkan_noise_level_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xNcnnVulkanNoiseLevelSpinBox')
|
||||
self.waifu2x_ncnn_vulkan_tile_size_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xNcnnVulkanTileSizeSpinBox')
|
||||
self.waifu2x_ncnn_vulkan_model_combo_box = self.findChild(QtWidgets.QComboBox, 'waifu2xNcnnVulkanModelComboBox')
|
||||
self.waifu2x_ncnn_vulkan_gpu_id_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xNcnnVulkanGpuIdSpinBox')
|
||||
self.waifu2x_ncnn_vulkan_jobs_line_edit = self.findChild(QtWidgets.QLineEdit, 'waifu2xNcnnVulkanJobsLineEdit')
|
||||
self.waifu2x_ncnn_vulkan_tta_check_box = self.findChild(QtWidgets.QCheckBox, 'waifu2xNcnnVulkanTtaCheckBox')
|
||||
self.waifu2x_ncnn_vulkan_noise_level_spin_box = self.findChild(QSpinBox, 'waifu2xNcnnVulkanNoiseLevelSpinBox')
|
||||
self.waifu2x_ncnn_vulkan_tile_size_spin_box = self.findChild(QSpinBox, 'waifu2xNcnnVulkanTileSizeSpinBox')
|
||||
self.waifu2x_ncnn_vulkan_model_combo_box = self.findChild(QComboBox, 'waifu2xNcnnVulkanModelComboBox')
|
||||
self.waifu2x_ncnn_vulkan_gpu_id_spin_box = self.findChild(QSpinBox, 'waifu2xNcnnVulkanGpuIdSpinBox')
|
||||
self.waifu2x_ncnn_vulkan_jobs_line_edit = self.findChild(QLineEdit, 'waifu2xNcnnVulkanJobsLineEdit')
|
||||
self.waifu2x_ncnn_vulkan_tta_check_box = self.findChild(QCheckBox, 'waifu2xNcnnVulkanTtaCheckBox')
|
||||
|
||||
# srmd-ncnn-vulkan
|
||||
self.srmd_ncnn_vulkan_path_line_edit = self.findChild(QtWidgets.QLineEdit, 'srmdNcnnVulkanPathLineEdit')
|
||||
self.srmd_ncnn_vulkan_path_line_edit = self.findChild(QLineEdit, 'srmdNcnnVulkanPathLineEdit')
|
||||
self.enable_line_edit_file_drop(self.srmd_ncnn_vulkan_path_line_edit)
|
||||
self.srmd_ncnn_vulkan_path_select_button = self.findChild(QtWidgets.QPushButton, 'srmdNcnnVulkanPathSelectButton')
|
||||
self.srmd_ncnn_vulkan_path_select_button = self.findChild(QPushButton, 'srmdNcnnVulkanPathSelectButton')
|
||||
self.srmd_ncnn_vulkan_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.srmd_ncnn_vulkan_path_line_edit))
|
||||
self.srmd_ncnn_vulkan_noise_level_spin_box = self.findChild(QtWidgets.QSpinBox, 'srmdNcnnVulkanNoiseLevelSpinBox')
|
||||
self.srmd_ncnn_vulkan_tile_size_spin_box = self.findChild(QtWidgets.QSpinBox, 'srmdNcnnVulkanTileSizeSpinBox')
|
||||
self.srmd_ncnn_vulkan_model_combo_box = self.findChild(QtWidgets.QComboBox, 'srmdNcnnVulkanModelComboBox')
|
||||
self.srmd_ncnn_vulkan_gpu_id_spin_box = self.findChild(QtWidgets.QSpinBox, 'srmdNcnnVulkanGpuIdSpinBox')
|
||||
self.srmd_ncnn_vulkan_jobs_line_edit = self.findChild(QtWidgets.QLineEdit, 'srmdNcnnVulkanJobsLineEdit')
|
||||
self.srmd_ncnn_vulkan_tta_check_box = self.findChild(QtWidgets.QCheckBox, 'srmdNcnnVulkanTtaCheckBox')
|
||||
self.srmd_ncnn_vulkan_noise_level_spin_box = self.findChild(QSpinBox, 'srmdNcnnVulkanNoiseLevelSpinBox')
|
||||
self.srmd_ncnn_vulkan_tile_size_spin_box = self.findChild(QSpinBox, 'srmdNcnnVulkanTileSizeSpinBox')
|
||||
self.srmd_ncnn_vulkan_model_combo_box = self.findChild(QComboBox, 'srmdNcnnVulkanModelComboBox')
|
||||
self.srmd_ncnn_vulkan_gpu_id_spin_box = self.findChild(QSpinBox, 'srmdNcnnVulkanGpuIdSpinBox')
|
||||
self.srmd_ncnn_vulkan_jobs_line_edit = self.findChild(QLineEdit, 'srmdNcnnVulkanJobsLineEdit')
|
||||
self.srmd_ncnn_vulkan_tta_check_box = self.findChild(QCheckBox, 'srmdNcnnVulkanTtaCheckBox')
|
||||
|
||||
# anime4k
|
||||
self.anime4kcpp_path_line_edit = self.findChild(QtWidgets.QLineEdit, 'anime4kCppPathLineEdit')
|
||||
self.anime4kcpp_path_line_edit = self.findChild(QLineEdit, 'anime4kCppPathLineEdit')
|
||||
self.enable_line_edit_file_drop(self.anime4kcpp_path_line_edit)
|
||||
self.anime4kcpp_path_select_button = self.findChild(QtWidgets.QPushButton, 'anime4kCppPathSelectButton')
|
||||
self.anime4kcpp_path_select_button = self.findChild(QPushButton, 'anime4kCppPathSelectButton')
|
||||
self.anime4kcpp_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.anime4kcpp_path_line_edit))
|
||||
self.anime4kcpp_passes_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppPassesSpinBox')
|
||||
self.anime4kcpp_push_color_count_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppPushColorCountSpinBox')
|
||||
self.anime4kcpp_strength_color_spin_box = self.findChild(QtWidgets.QDoubleSpinBox, 'anime4kCppStrengthColorSpinBox')
|
||||
self.anime4kcpp_strength_gradient_spin_box = self.findChild(QtWidgets.QDoubleSpinBox, 'anime4kCppStrengthGradientSpinBox')
|
||||
self.anime4kcpp_threads_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppThreadsSpinBox')
|
||||
self.anime4kcpp_pre_filters_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppPreFiltersSpinBox')
|
||||
self.anime4kcpp_post_filters_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppPostFiltersSpinBox')
|
||||
self.anime4kcpp_platform_id_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppPlatformIdSpinBox')
|
||||
self.anime4kcpp_device_id_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppDeviceIdSpinBox')
|
||||
self.anime4kcpp_codec_combo_box = self.findChild(QtWidgets.QComboBox, 'anime4kCppCodecComboBox')
|
||||
self.anime4kcpp_fast_mode_check_box = self.findChild(QtWidgets.QCheckBox, 'anime4kCppFastModeCheckBox')
|
||||
self.anime4kcpp_pre_processing_check_box = self.findChild(QtWidgets.QCheckBox, 'anime4kCppPreProcessingCheckBox')
|
||||
self.anime4kcpp_post_processing_check_box = self.findChild(QtWidgets.QCheckBox, 'anime4kCppPostProcessingCheckBox')
|
||||
self.anime4kcpp_gpu_mode_check_box = self.findChild(QtWidgets.QCheckBox, 'anime4kCppGpuModeCheckBox')
|
||||
self.anime4kcpp_passes_spin_box = self.findChild(QSpinBox, 'anime4kCppPassesSpinBox')
|
||||
self.anime4kcpp_push_color_count_spin_box = self.findChild(QSpinBox, 'anime4kCppPushColorCountSpinBox')
|
||||
self.anime4kcpp_strength_color_spin_box = self.findChild(QDoubleSpinBox, 'anime4kCppStrengthColorSpinBox')
|
||||
self.anime4kcpp_strength_gradient_spin_box = self.findChild(QDoubleSpinBox, 'anime4kCppStrengthGradientSpinBox')
|
||||
self.anime4kcpp_threads_spin_box = self.findChild(QSpinBox, 'anime4kCppThreadsSpinBox')
|
||||
self.anime4kcpp_pre_filters_spin_box = self.findChild(QSpinBox, 'anime4kCppPreFiltersSpinBox')
|
||||
self.anime4kcpp_post_filters_spin_box = self.findChild(QSpinBox, 'anime4kCppPostFiltersSpinBox')
|
||||
self.anime4kcpp_platform_id_spin_box = self.findChild(QSpinBox, 'anime4kCppPlatformIdSpinBox')
|
||||
self.anime4kcpp_device_id_spin_box = self.findChild(QSpinBox, 'anime4kCppDeviceIdSpinBox')
|
||||
self.anime4kcpp_codec_combo_box = self.findChild(QComboBox, 'anime4kCppCodecComboBox')
|
||||
self.anime4kcpp_fast_mode_check_box = self.findChild(QCheckBox, 'anime4kCppFastModeCheckBox')
|
||||
self.anime4kcpp_pre_processing_check_box = self.findChild(QCheckBox, 'anime4kCppPreProcessingCheckBox')
|
||||
self.anime4kcpp_post_processing_check_box = self.findChild(QCheckBox, 'anime4kCppPostProcessingCheckBox')
|
||||
self.anime4kcpp_gpu_mode_check_box = self.findChild(QCheckBox, 'anime4kCppGpuModeCheckBox')
|
||||
|
||||
# load configurations
|
||||
self.load_configurations()
|
||||
@ -250,11 +312,15 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
||||
event.ignore()
|
||||
|
||||
def dropEvent(self, event):
|
||||
input_path = pathlib.Path(event.mimeData().urls()[0].toLocalFile())
|
||||
self.input_line_edit.setText(str(input_path.absolute()))
|
||||
self.generate_output_path(input_path)
|
||||
input_paths = [pathlib.Path(u.toLocalFile()) for u in event.mimeData().urls()]
|
||||
for path in input_paths:
|
||||
if (path.is_file() or path.is_dir()) and not self.input_table_path_exists(path):
|
||||
self.input_table_data.append(path)
|
||||
|
||||
def enable_line_edit_file_drop(self, line_edit: QtWidgets.QLineEdit):
|
||||
self.update_input_table()
|
||||
self.update_output_path()
|
||||
|
||||
def enable_line_edit_file_drop(self, line_edit: QLineEdit):
|
||||
line_edit.dragEnterEvent = self.dragEnterEvent
|
||||
line_edit.dropEvent = lambda event: line_edit.setText(str(pathlib.Path(event.mimeData().urls()[0].toLocalFile()).absolute()))
|
||||
|
||||
@ -279,7 +345,7 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
||||
|
||||
# if file doesn't exist, return
|
||||
if not config_file_path.is_file():
|
||||
QtWidgets.QErrorMessage(self).showMessage('Video2X configuration file not found, please specify manually.')
|
||||
QErrorMessage(self).showMessage('Video2X configuration file not found, please specify manually.')
|
||||
return
|
||||
|
||||
# read configuration dict from config file
|
||||
@ -438,19 +504,50 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
||||
else:
|
||||
self.processes_spin_box.setValue(1)
|
||||
|
||||
def update_input_table(self):
|
||||
# HACK: use insertRow, removeRow and signals
|
||||
del self.input_table_model
|
||||
self.input_table_model = InputTableModel(self.input_table_data)
|
||||
self.input_table_view.setModel(self.input_table_model)
|
||||
|
||||
def input_table_delete_selected(self):
|
||||
items_to_delete = []
|
||||
for index in [i.row() for i in self.input_table_view.selectedIndexes()]:
|
||||
items_to_delete.append(self.input_table_data[index])
|
||||
|
||||
for item in items_to_delete:
|
||||
self.input_table_data.remove(item)
|
||||
self.update_input_table()
|
||||
|
||||
def input_table_clear_all(self):
|
||||
self.input_table_data = []
|
||||
self.update_input_table()
|
||||
|
||||
def input_table_path_exists(self, input_path):
|
||||
for path in self.input_table_data:
|
||||
# not using Path.samefile since file may not exist
|
||||
if str(path.absolute()) == str(input_path.absolute()):
|
||||
return True
|
||||
return False
|
||||
|
||||
def select_file(self, *args, **kwargs) -> pathlib.Path:
|
||||
file_selected = QtWidgets.QFileDialog.getOpenFileName(self, *args, **kwargs)
|
||||
file_selected = QFileDialog.getOpenFileName(self, *args, **kwargs)
|
||||
if not isinstance(file_selected, tuple) or file_selected[0] == '':
|
||||
return None
|
||||
return pathlib.Path(file_selected[0])
|
||||
|
||||
def select_folder(self, *args, **kwargs) -> pathlib.Path:
|
||||
folder_selected = QtWidgets.QFileDialog.getExistingDirectory(self, *args, **kwargs)
|
||||
folder_selected = QFileDialog.getExistingDirectory(self, *args, **kwargs)
|
||||
if folder_selected == '':
|
||||
return None
|
||||
return pathlib.Path(folder_selected)
|
||||
|
||||
def generate_output_path(self, input_path: pathlib.Path):
|
||||
def update_output_path(self):
|
||||
# if there is more than one input
|
||||
if len(self.input_table_data) != 1:
|
||||
return
|
||||
|
||||
input_path = self.input_table_data[0]
|
||||
# give up if input path doesn't exist or isn't a file or a directory
|
||||
if not input_path.exists() or not (input_path.is_file() or input_path.is_dir()):
|
||||
return
|
||||
@ -466,23 +563,27 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
||||
if input_path.is_file():
|
||||
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_path_id}.mp4')
|
||||
elif input_path.is_dir():
|
||||
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_file_id}')
|
||||
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_path_id}')
|
||||
output_path_id += 1
|
||||
|
||||
if not output_path.exists():
|
||||
self.output_line_edit.setText(str(output_path.absolute()))
|
||||
|
||||
def select_input_file(self):
|
||||
if (input_file := self.select_file('Select Input File')) is None:
|
||||
if ((input_file := self.select_file('Select Input File')) is None or
|
||||
self.input_table_path_exists(input_file)):
|
||||
return
|
||||
self.generate_output_path(input_file)
|
||||
self.input_line_edit.setText(str(input_file.absolute()))
|
||||
self.input_table_data.append(input_file)
|
||||
self.update_output_path()
|
||||
self.update_input_table()
|
||||
|
||||
def select_input_folder(self):
|
||||
if (input_folder := self.select_folder('Select Input Folder')) is None:
|
||||
if ((input_folder := self.select_folder('Select Input Folder')) is None or
|
||||
self.input_table_path_exists(input_folder)):
|
||||
return
|
||||
self.generate_output_path(input_folder)
|
||||
self.input_line_edit.setText(str(input_folder.absolute()))
|
||||
self.input_table_data.append(input_folder)
|
||||
self.update_output_path()
|
||||
self.update_input_table()
|
||||
|
||||
def select_output_file(self):
|
||||
if (output_file := self.select_file('Select Output File')) is None:
|
||||
@ -511,15 +612,15 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
||||
driver_line_edit.setText(str(driver_binary_path.absolute()))
|
||||
|
||||
def show_error(self, message: str):
|
||||
QtWidgets.QErrorMessage(self).showMessage(message.replace('\n', '<br>'))
|
||||
QErrorMessage(self).showMessage(message.replace('\n', '<br>'))
|
||||
|
||||
def show_message(self, message: str, custom_icon=None):
|
||||
message_box = QtWidgets.QMessageBox()
|
||||
message_box = QMessageBox()
|
||||
message_box.setWindowTitle('Message')
|
||||
if custom_icon:
|
||||
message_box.setIconPixmap(custom_icon.scaled(64, 64))
|
||||
else:
|
||||
message_box.setIcon(QtWidgets.QMessageBox.Information)
|
||||
message_box.setIcon(QMessageBox.Information)
|
||||
message_box.setText(message)
|
||||
message_box.exec_()
|
||||
|
||||
@ -580,14 +681,17 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
||||
self.begin_time = time.time()
|
||||
|
||||
# resolve input and output directories from GUI
|
||||
if self.input_line_edit.text().strip() == '':
|
||||
self.show_error('Input path not specified')
|
||||
if len(self.input_table_data) == 0:
|
||||
self.show_error('Input path unspecified')
|
||||
return
|
||||
if self.output_line_edit.text().strip() == '':
|
||||
self.show_error('Output path not specified')
|
||||
self.show_error('Output path unspecified')
|
||||
return
|
||||
|
||||
input_directory = pathlib.Path(os.path.expandvars(self.input_line_edit.text()))
|
||||
if len(self.input_table_data) == 1:
|
||||
input_directory = self.input_table_data[0]
|
||||
else:
|
||||
input_directory = self.input_table_data
|
||||
output_directory = pathlib.Path(os.path.expandvars(self.output_line_edit.text()))
|
||||
|
||||
# load driver settings from GUI
|
||||
@ -658,7 +762,7 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
||||
|
||||
# this file shouldn't be imported
|
||||
if __name__ == '__main__':
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
app = QApplication(sys.argv)
|
||||
window = Video2XMainWindow()
|
||||
window.show()
|
||||
app.exec_()
|
||||
|
@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>691</width>
|
||||
<height>503</height>
|
||||
<width>718</width>
|
||||
<height>668</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
@ -16,7 +16,7 @@
|
||||
<property name="windowTitle">
|
||||
<string>Video2X GUI</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>5</number>
|
||||
@ -79,34 +79,16 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="fileSelectionVerticalLayout">
|
||||
<widget class="QGroupBox" name="inputSelectionGroupBox">
|
||||
<property name="title">
|
||||
<string>Input Selection</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="inputHorizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="inputLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>63</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Input</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTableView" name="inputTableView"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="inputLineEdit"/>
|
||||
</item>
|
||||
<layout class="QHBoxLayout" name="inputButtonsHorizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="inputSelectFileButton">
|
||||
<property name="enabled">
|
||||
@ -124,8 +106,31 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="inputDeleteSelectedButton">
|
||||
<property name="text">
|
||||
<string>Delete Selected</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="inputClearAllButton">
|
||||
<property name="text">
|
||||
<string>Clear All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="otherPathsSelectionGroupBox">
|
||||
<property name="title">
|
||||
<string>Other Paths Selection</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="outputHorizontalLayout">
|
||||
<item>
|
||||
@ -227,6 +232,7 @@
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="expressSettingsGroupBox">
|
||||
@ -1344,7 +1350,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>691</width>
|
||||
<width>718</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
Loading…
Reference in New Issue
Block a user