mirror of
https://github.com/283375/arcaea-offline-pyside-ui.git
synced 2025-07-01 20:36:26 +00:00
feat: TabOcr_BuildPHashDatabase
This commit is contained in:
255
ui/designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui
Normal file
255
ui/designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>tabOcr_BuildPHashDatabase</class>
|
||||||
|
<widget class="QWidget" name="tabOcr_BuildPHashDatabase">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>632</width>
|
||||||
|
<height>551</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string notr="true">tabOcr_BuildPHashDatabase</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>folders.title</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>folders.songDir</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="FileSelector" name="songDirSelector" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>folders.charIconDir</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="FileSelector" name="charIconDirSelector" native="true">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
|
<property name="title">
|
||||||
|
<string>options.title</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">hash_size</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="hashSizeSpinBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>64</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>16</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">highfreq_factor</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="highfreqFactorSpinBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>32</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>4</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="optionsResetButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>resetButton</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QProgressBar" name="progressBar">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
<property name="format">
|
||||||
|
<string notr="true">%v/%m - %p%</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="buildButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>buildButton</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="verticalSpacer_2">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>20</width>
|
||||||
|
<height>40</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>FileSelector</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>ui.implements.components.fileSelector</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
193
ui/designer/tabs/tabOcr/tabOcr_BuildPHashDatabase_ui.py
Normal file
193
ui/designer/tabs/tabOcr/tabOcr_BuildPHashDatabase_ui.py
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
## Form generated from reading UI file 'tabOcr_BuildPHashDatabase.ui'
|
||||||
|
##
|
||||||
|
## Created by: Qt User Interface Compiler version 6.5.2
|
||||||
|
##
|
||||||
|
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
||||||
|
QMetaObject, QObject, QPoint, QRect,
|
||||||
|
QSize, QTime, QUrl, Qt)
|
||||||
|
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
||||||
|
QFont, QFontDatabase, QGradient, QIcon,
|
||||||
|
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||||
|
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||||
|
from PySide6.QtWidgets import (QApplication, QGroupBox, QHBoxLayout, QLabel,
|
||||||
|
QProgressBar, QPushButton, QSizePolicy, QSpacerItem,
|
||||||
|
QSpinBox, QVBoxLayout, QWidget)
|
||||||
|
|
||||||
|
from ui.implements.components.fileSelector import FileSelector
|
||||||
|
|
||||||
|
class Ui_tabOcr_BuildPHashDatabase(object):
|
||||||
|
def setupUi(self, tabOcr_BuildPHashDatabase):
|
||||||
|
if not tabOcr_BuildPHashDatabase.objectName():
|
||||||
|
tabOcr_BuildPHashDatabase.setObjectName(u"tabOcr_BuildPHashDatabase")
|
||||||
|
tabOcr_BuildPHashDatabase.resize(632, 551)
|
||||||
|
tabOcr_BuildPHashDatabase.setWindowTitle(u"tabOcr_BuildPHashDatabase")
|
||||||
|
self.verticalLayout_3 = QVBoxLayout(tabOcr_BuildPHashDatabase)
|
||||||
|
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
||||||
|
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||||||
|
|
||||||
|
self.verticalLayout_3.addItem(self.verticalSpacer)
|
||||||
|
|
||||||
|
self.groupBox = QGroupBox(tabOcr_BuildPHashDatabase)
|
||||||
|
self.groupBox.setObjectName(u"groupBox")
|
||||||
|
self.verticalLayout = QVBoxLayout(self.groupBox)
|
||||||
|
self.verticalLayout.setObjectName(u"verticalLayout")
|
||||||
|
self.horizontalLayout = QHBoxLayout()
|
||||||
|
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||||
|
self.label = QLabel(self.groupBox)
|
||||||
|
self.label.setObjectName(u"label")
|
||||||
|
|
||||||
|
self.horizontalLayout.addWidget(self.label)
|
||||||
|
|
||||||
|
self.songDirSelector = FileSelector(self.groupBox)
|
||||||
|
self.songDirSelector.setObjectName(u"songDirSelector")
|
||||||
|
sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.songDirSelector.sizePolicy().hasHeightForWidth())
|
||||||
|
self.songDirSelector.setSizePolicy(sizePolicy)
|
||||||
|
|
||||||
|
self.horizontalLayout.addWidget(self.songDirSelector)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||||
|
|
||||||
|
self.horizontalLayout_2 = QHBoxLayout()
|
||||||
|
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
||||||
|
self.label_2 = QLabel(self.groupBox)
|
||||||
|
self.label_2.setObjectName(u"label_2")
|
||||||
|
|
||||||
|
self.horizontalLayout_2.addWidget(self.label_2)
|
||||||
|
|
||||||
|
self.charIconDirSelector = FileSelector(self.groupBox)
|
||||||
|
self.charIconDirSelector.setObjectName(u"charIconDirSelector")
|
||||||
|
sizePolicy.setHeightForWidth(self.charIconDirSelector.sizePolicy().hasHeightForWidth())
|
||||||
|
self.charIconDirSelector.setSizePolicy(sizePolicy)
|
||||||
|
|
||||||
|
self.horizontalLayout_2.addWidget(self.charIconDirSelector)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout_3.addWidget(self.groupBox)
|
||||||
|
|
||||||
|
self.groupBox_2 = QGroupBox(tabOcr_BuildPHashDatabase)
|
||||||
|
self.groupBox_2.setObjectName(u"groupBox_2")
|
||||||
|
self.horizontalLayout_3 = QHBoxLayout(self.groupBox_2)
|
||||||
|
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
||||||
|
self.verticalLayout_2 = QVBoxLayout()
|
||||||
|
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
||||||
|
self.horizontalLayout_6 = QHBoxLayout()
|
||||||
|
self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
|
||||||
|
self.label_3 = QLabel(self.groupBox_2)
|
||||||
|
self.label_3.setObjectName(u"label_3")
|
||||||
|
self.label_3.setText(u"hash_size")
|
||||||
|
self.label_3.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
|
||||||
|
|
||||||
|
self.horizontalLayout_6.addWidget(self.label_3)
|
||||||
|
|
||||||
|
self.hashSizeSpinBox = QSpinBox(self.groupBox_2)
|
||||||
|
self.hashSizeSpinBox.setObjectName(u"hashSizeSpinBox")
|
||||||
|
sizePolicy1 = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
|
||||||
|
sizePolicy1.setHorizontalStretch(0)
|
||||||
|
sizePolicy1.setVerticalStretch(0)
|
||||||
|
sizePolicy1.setHeightForWidth(self.hashSizeSpinBox.sizePolicy().hasHeightForWidth())
|
||||||
|
self.hashSizeSpinBox.setSizePolicy(sizePolicy1)
|
||||||
|
self.hashSizeSpinBox.setMinimum(2)
|
||||||
|
self.hashSizeSpinBox.setMaximum(64)
|
||||||
|
self.hashSizeSpinBox.setValue(16)
|
||||||
|
|
||||||
|
self.horizontalLayout_6.addWidget(self.hashSizeSpinBox)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout_2.addLayout(self.horizontalLayout_6)
|
||||||
|
|
||||||
|
self.horizontalLayout_7 = QHBoxLayout()
|
||||||
|
self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
|
||||||
|
self.label_4 = QLabel(self.groupBox_2)
|
||||||
|
self.label_4.setObjectName(u"label_4")
|
||||||
|
self.label_4.setText(u"highfreq_factor")
|
||||||
|
self.label_4.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
|
||||||
|
|
||||||
|
self.horizontalLayout_7.addWidget(self.label_4)
|
||||||
|
|
||||||
|
self.highfreqFactorSpinBox = QSpinBox(self.groupBox_2)
|
||||||
|
self.highfreqFactorSpinBox.setObjectName(u"highfreqFactorSpinBox")
|
||||||
|
sizePolicy1.setHeightForWidth(self.highfreqFactorSpinBox.sizePolicy().hasHeightForWidth())
|
||||||
|
self.highfreqFactorSpinBox.setSizePolicy(sizePolicy1)
|
||||||
|
self.highfreqFactorSpinBox.setMaximum(32)
|
||||||
|
self.highfreqFactorSpinBox.setValue(4)
|
||||||
|
|
||||||
|
self.horizontalLayout_7.addWidget(self.highfreqFactorSpinBox)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout_2.addLayout(self.horizontalLayout_7)
|
||||||
|
|
||||||
|
|
||||||
|
self.horizontalLayout_3.addLayout(self.verticalLayout_2)
|
||||||
|
|
||||||
|
self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||||
|
|
||||||
|
self.horizontalLayout_3.addItem(self.horizontalSpacer_3)
|
||||||
|
|
||||||
|
self.optionsResetButton = QPushButton(self.groupBox_2)
|
||||||
|
self.optionsResetButton.setObjectName(u"optionsResetButton")
|
||||||
|
|
||||||
|
self.horizontalLayout_3.addWidget(self.optionsResetButton)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout_3.addWidget(self.groupBox_2)
|
||||||
|
|
||||||
|
self.progressBar = QProgressBar(tabOcr_BuildPHashDatabase)
|
||||||
|
self.progressBar.setObjectName(u"progressBar")
|
||||||
|
self.progressBar.setMaximum(0)
|
||||||
|
self.progressBar.setValue(0)
|
||||||
|
self.progressBar.setAlignment(Qt.AlignCenter)
|
||||||
|
self.progressBar.setFormat(u"%v/%m - %p%")
|
||||||
|
|
||||||
|
self.verticalLayout_3.addWidget(self.progressBar)
|
||||||
|
|
||||||
|
self.horizontalLayout_5 = QHBoxLayout()
|
||||||
|
self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
|
||||||
|
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||||
|
|
||||||
|
self.horizontalLayout_5.addItem(self.horizontalSpacer)
|
||||||
|
|
||||||
|
self.buildButton = QPushButton(tabOcr_BuildPHashDatabase)
|
||||||
|
self.buildButton.setObjectName(u"buildButton")
|
||||||
|
|
||||||
|
self.horizontalLayout_5.addWidget(self.buildButton)
|
||||||
|
|
||||||
|
self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||||
|
|
||||||
|
self.horizontalLayout_5.addItem(self.horizontalSpacer_2)
|
||||||
|
|
||||||
|
|
||||||
|
self.verticalLayout_3.addLayout(self.horizontalLayout_5)
|
||||||
|
|
||||||
|
self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||||||
|
|
||||||
|
self.verticalLayout_3.addItem(self.verticalSpacer_2)
|
||||||
|
|
||||||
|
|
||||||
|
self.retranslateUi(tabOcr_BuildPHashDatabase)
|
||||||
|
|
||||||
|
QMetaObject.connectSlotsByName(tabOcr_BuildPHashDatabase)
|
||||||
|
# setupUi
|
||||||
|
|
||||||
|
def retranslateUi(self, tabOcr_BuildPHashDatabase):
|
||||||
|
self.groupBox.setTitle(QCoreApplication.translate("tabOcr_BuildPHashDatabase", u"folders.title", None))
|
||||||
|
self.label.setText(QCoreApplication.translate("tabOcr_BuildPHashDatabase", u"folders.songDir", None))
|
||||||
|
self.label_2.setText(QCoreApplication.translate("tabOcr_BuildPHashDatabase", u"folders.charIconDir", None))
|
||||||
|
self.groupBox_2.setTitle(QCoreApplication.translate("tabOcr_BuildPHashDatabase", u"options.title", None))
|
||||||
|
self.optionsResetButton.setText(QCoreApplication.translate("tabOcr_BuildPHashDatabase", u"resetButton", None))
|
||||||
|
self.buildButton.setText(QCoreApplication.translate("tabOcr_BuildPHashDatabase", u"buildButton", None))
|
||||||
|
pass
|
||||||
|
# retranslateUi
|
||||||
|
|
@ -29,6 +29,11 @@
|
|||||||
<string>tab.b30</string>
|
<string>tab.b30</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="TabOcr_BuildPHashDatabase" name="tab_3">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>tab.buildPHashDatabase</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
@ -46,6 +51,12 @@
|
|||||||
<header>ui.implements.tabs.tabOcr.tabOcr_B30</header>
|
<header>ui.implements.tabs.tabOcr.tabOcr_B30</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>TabOcr_BuildPHashDatabase</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>ui.implements.tabs.tabOcr.tabOcr_BuildPHashDatabase</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
## Form generated from reading UI file 'tabOcrEntry.ui'
|
## Form generated from reading UI file 'tabOcrEntry.ui'
|
||||||
##
|
##
|
||||||
## Created by: Qt User Interface Compiler version 6.5.1
|
## Created by: Qt User Interface Compiler version 6.5.2
|
||||||
##
|
##
|
||||||
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -19,6 +19,7 @@ from PySide6.QtWidgets import (QApplication, QSizePolicy, QTabWidget, QVBoxLayou
|
|||||||
QWidget)
|
QWidget)
|
||||||
|
|
||||||
from ui.implements.tabs.tabOcr.tabOcr_B30 import TabOcr_B30
|
from ui.implements.tabs.tabOcr.tabOcr_B30 import TabOcr_B30
|
||||||
|
from ui.implements.tabs.tabOcr.tabOcr_BuildPHashDatabase import TabOcr_BuildPHashDatabase
|
||||||
from ui.implements.tabs.tabOcr.tabOcr_Device import TabOcr_Device
|
from ui.implements.tabs.tabOcr.tabOcr_Device import TabOcr_Device
|
||||||
|
|
||||||
class Ui_TabOcrEntry(object):
|
class Ui_TabOcrEntry(object):
|
||||||
@ -37,6 +38,9 @@ class Ui_TabOcrEntry(object):
|
|||||||
self.tab_2 = TabOcr_B30()
|
self.tab_2 = TabOcr_B30()
|
||||||
self.tab_2.setObjectName(u"tab_2")
|
self.tab_2.setObjectName(u"tab_2")
|
||||||
self.tabWidget.addTab(self.tab_2, "")
|
self.tabWidget.addTab(self.tab_2, "")
|
||||||
|
self.tab_3 = TabOcr_BuildPHashDatabase()
|
||||||
|
self.tab_3.setObjectName(u"tab_3")
|
||||||
|
self.tabWidget.addTab(self.tab_3, "")
|
||||||
|
|
||||||
self.verticalLayout.addWidget(self.tabWidget)
|
self.verticalLayout.addWidget(self.tabWidget)
|
||||||
|
|
||||||
@ -52,6 +56,7 @@ class Ui_TabOcrEntry(object):
|
|||||||
def retranslateUi(self, TabOcrEntry):
|
def retranslateUi(self, TabOcrEntry):
|
||||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QCoreApplication.translate("TabOcrEntry", u"tab.device", None))
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QCoreApplication.translate("TabOcrEntry", u"tab.device", None))
|
||||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QCoreApplication.translate("TabOcrEntry", u"tab.b30", None))
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QCoreApplication.translate("TabOcrEntry", u"tab.b30", None))
|
||||||
|
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), QCoreApplication.translate("TabOcrEntry", u"tab.buildPHashDatabase", None))
|
||||||
pass
|
pass
|
||||||
# retranslateUi
|
# retranslateUi
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
from .build_phash import build_image_phash_database
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import json
|
import json
|
||||||
|
|
61
ui/extends/ocr/build_phash.py
Normal file
61
ui/extends/ocr/build_phash.py
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import sqlite3
|
||||||
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any, Callable, Optional
|
||||||
|
|
||||||
|
import cv2
|
||||||
|
from arcaea_offline_ocr.phash_db import phash_opencv
|
||||||
|
|
||||||
|
|
||||||
|
def build_image_phash_database(
|
||||||
|
images: list[Path],
|
||||||
|
labels: list[str],
|
||||||
|
*,
|
||||||
|
hash_size: int = 16,
|
||||||
|
highfreq_factor: int = 4,
|
||||||
|
progress_func: Optional[Callable[[int, int], Any]] = None,
|
||||||
|
):
|
||||||
|
assert len(images) == len(labels)
|
||||||
|
|
||||||
|
conn = sqlite3.connect(":memory:", check_same_thread=False)
|
||||||
|
|
||||||
|
with conn:
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
cursor.execute("CREATE TABLE properties (key TEXT, value TEXT)")
|
||||||
|
cursor.executemany(
|
||||||
|
"INSERT INTO properties VALUES (?, ?)",
|
||||||
|
[
|
||||||
|
("hash_size", hash_size),
|
||||||
|
("highfreq_factor", highfreq_factor),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
image_num = len(images)
|
||||||
|
id_hashes = []
|
||||||
|
for i, label, image_path in zip(range(image_num), labels, images):
|
||||||
|
image_hash = phash_opencv(
|
||||||
|
cv2.imread(str(image_path.resolve()), cv2.IMREAD_GRAYSCALE),
|
||||||
|
hash_size=hash_size,
|
||||||
|
highfreq_factor=highfreq_factor,
|
||||||
|
)
|
||||||
|
image_hash_bytes = image_hash.flatten().tobytes()
|
||||||
|
|
||||||
|
id_hashes.append([label, image_hash_bytes])
|
||||||
|
if progress_func:
|
||||||
|
progress_func(i + 1, image_num)
|
||||||
|
|
||||||
|
hash_length = len(id_hashes[0][1])
|
||||||
|
cursor.execute(f"CREATE TABLE hashes (id TEXT, hash BLOB({hash_length}))")
|
||||||
|
|
||||||
|
cursor.executemany(
|
||||||
|
"INSERT INTO hashes VALUES (?, ?)",
|
||||||
|
id_hashes,
|
||||||
|
)
|
||||||
|
cursor.executemany(
|
||||||
|
"INSERT INTO properties VALUES (?, ?)",
|
||||||
|
[("built_timestamp", int(time.time()))],
|
||||||
|
)
|
||||||
|
conn.commit()
|
||||||
|
|
||||||
|
return conn
|
138
ui/implements/tabs/tabOcr/tabOcr_BuildPHashDatabase.py
Normal file
138
ui/implements/tabs/tabOcr/tabOcr_BuildPHashDatabase.py
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
import logging
|
||||||
|
import re
|
||||||
|
import sqlite3
|
||||||
|
import time
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from PySide6.QtCore import QThread, Signal, Slot
|
||||||
|
from PySide6.QtWidgets import QFileDialog, QMessageBox, QWidget
|
||||||
|
|
||||||
|
from ui.designer.tabs.tabOcr.tabOcr_BuildPHashDatabase_ui import (
|
||||||
|
Ui_tabOcr_BuildPHashDatabase,
|
||||||
|
)
|
||||||
|
from ui.extends.ocr import build_image_phash_database
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildDatabaseThread(QThread):
|
||||||
|
conn: sqlite3.Connection
|
||||||
|
|
||||||
|
progress = Signal(int, int)
|
||||||
|
success = Signal()
|
||||||
|
error = Signal(str)
|
||||||
|
finished = Signal()
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
images: list[Path],
|
||||||
|
labels: list[str],
|
||||||
|
*,
|
||||||
|
hashSize: int | None = None,
|
||||||
|
highfreqFactor: int | None = None,
|
||||||
|
):
|
||||||
|
super().__init__()
|
||||||
|
self.images = images
|
||||||
|
self.labels = labels
|
||||||
|
self.hashSize = hashSize
|
||||||
|
self.highfreqFactor = highfreqFactor
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
try:
|
||||||
|
progressFunc = lambda i, total: self.progress.emit(i, total)
|
||||||
|
|
||||||
|
kwargsDict = {}
|
||||||
|
if self.hashSize is not None:
|
||||||
|
kwargsDict["hash_size"] = self.hashSize
|
||||||
|
if self.highfreqFactor is not None:
|
||||||
|
kwargsDict["highfreq_factor"] = self.highfreqFactor
|
||||||
|
self.conn = build_image_phash_database(
|
||||||
|
self.images, self.labels, progress_func=progressFunc, **kwargsDict
|
||||||
|
)
|
||||||
|
self.success.emit()
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error during pHash database build")
|
||||||
|
self.error.emit(str(e))
|
||||||
|
finally:
|
||||||
|
self.finished.emit()
|
||||||
|
|
||||||
|
|
||||||
|
class TabOcr_BuildPHashDatabase(Ui_tabOcr_BuildPHashDatabase, QWidget):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setupUi(self)
|
||||||
|
|
||||||
|
self.songDirSelector.setMode(self.songDirSelector.getExistingDirectory)
|
||||||
|
self.charIconDirSelector.setMode(self.charIconDirSelector.getExistingDirectory)
|
||||||
|
|
||||||
|
self.buildButton.clicked.connect(self.databaseBuildStart)
|
||||||
|
|
||||||
|
@Slot()
|
||||||
|
def on_optionsResetButton_clicked(self):
|
||||||
|
self.hashSizeSpinBox.setValue(16)
|
||||||
|
self.highfreqFactorSpinBox.setValue(4)
|
||||||
|
|
||||||
|
def databaseFileName(self):
|
||||||
|
return f"image-phash-{int(time.time() * 1000)}.db"
|
||||||
|
|
||||||
|
def databaseBuildStart(self):
|
||||||
|
if not self.songDirSelector.selectedFiles():
|
||||||
|
QMessageBox.critical(self, None, "Song directory not selected.")
|
||||||
|
return
|
||||||
|
if not self.charIconDirSelector.selectedFiles():
|
||||||
|
QMessageBox.critical(self, None, "Char icon directory not selected.")
|
||||||
|
return
|
||||||
|
|
||||||
|
songDir = self.songDirSelector.selectedFiles()[0]
|
||||||
|
charIconDir = self.charIconDirSelector.selectedFiles()[0]
|
||||||
|
|
||||||
|
acceptExts = [".jpg", ".png"]
|
||||||
|
songFilePaths = [
|
||||||
|
p for p in Path(songDir).glob("**/*") if p.suffix in acceptExts
|
||||||
|
]
|
||||||
|
charIconFilePaths = [
|
||||||
|
p for p in Path(charIconDir).glob("**/*") if p.suffix in acceptExts
|
||||||
|
]
|
||||||
|
songLabels = [re.sub(r"_.*$", "", p.stem) for p in songFilePaths]
|
||||||
|
charLabels = [f"character||{p.stem}" for p in charIconFilePaths]
|
||||||
|
|
||||||
|
self.databaseBuildThread = BuildDatabaseThread(
|
||||||
|
songFilePaths + charIconFilePaths, songLabels + charLabels
|
||||||
|
)
|
||||||
|
self.databaseBuildThread.progress.connect(self.databaseBuildProgress)
|
||||||
|
self.databaseBuildThread.success.connect(self.databaseBuildSuccess)
|
||||||
|
self.databaseBuildThread.error.connect(self.databaseBuildError)
|
||||||
|
self.buildButton.setEnabled(False)
|
||||||
|
self.databaseBuildThread.start()
|
||||||
|
|
||||||
|
@Slot(int, int)
|
||||||
|
def databaseBuildProgress(self, i: int, total: int):
|
||||||
|
if i < 5:
|
||||||
|
self.progressBar.setMaximum(total)
|
||||||
|
self.progressBar.setValue(i)
|
||||||
|
|
||||||
|
@Slot(str)
|
||||||
|
def databaseBuildError(self, msg: str):
|
||||||
|
QMessageBox.critical(self, "Error", msg)
|
||||||
|
self.databaseBuildCleanUp()
|
||||||
|
|
||||||
|
@Slot()
|
||||||
|
def databaseBuildSuccess(self):
|
||||||
|
dbMemory = self.databaseBuildThread.conn
|
||||||
|
|
||||||
|
dbFileName, _ = QFileDialog.getSaveFileName(self, None, self.databaseFileName())
|
||||||
|
if not dbFileName:
|
||||||
|
self.databaseBuildCleanUp()
|
||||||
|
QMessageBox.information(self, None, "User canceled operation.")
|
||||||
|
return
|
||||||
|
|
||||||
|
dbDisk = sqlite3.connect(dbFileName)
|
||||||
|
dbMemory.backup(dbDisk)
|
||||||
|
self.databaseBuildCleanUp()
|
||||||
|
|
||||||
|
def databaseBuildCleanUp(self):
|
||||||
|
self.databaseBuildThread.deleteLater()
|
||||||
|
self.databaseBuildThread = None
|
||||||
|
self.progressBar.setMaximum(0)
|
||||||
|
self.progressBar.setValue(0)
|
||||||
|
self.buildButton.setEnabled(True)
|
@ -89,12 +89,12 @@
|
|||||||
<translation>Continue</translation>
|
<translation>Continue</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../startup/databaseChecker.py" line="115"/>
|
<location filename="../../startup/databaseChecker.py" line="117"/>
|
||||||
<source>dialog.tryInitExistingDatabase</source>
|
<source>dialog.tryInitExistingDatabase</source>
|
||||||
<translation>The existing database doesn't seem to be initialized properly, try initialize again?</translation>
|
<translation>The existing database doesn't seem to be initialized properly, try initialize again?</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../startup/databaseChecker.py" line="131"/>
|
<location filename="../../startup/databaseChecker.py" line="133"/>
|
||||||
<source>dialog.confirmNewDatabase</source>
|
<source>dialog.confirmNewDatabase</source>
|
||||||
<translation>Database file does not exist. Create now?</translation>
|
<translation>Database file does not exist. Create now?</translation>
|
||||||
</message>
|
</message>
|
||||||
@ -696,6 +696,11 @@ validation</translation>
|
|||||||
<source>tab.b30</source>
|
<source>tab.b30</source>
|
||||||
<translation>B30</translation>
|
<translation>B30</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcrEntry.ui" line="34"/>
|
||||||
|
<source>tab.buildPHashDatabase</source>
|
||||||
|
<translation>Build pHash Database</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>TabOcr_B30</name>
|
<name>TabOcr_B30</name>
|
||||||
@ -1167,4 +1172,37 @@ validation</translation>
|
|||||||
<translation>Result (play rating)</translation>
|
<translation>Result (play rating)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>tabOcr_BuildPHashDatabase</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="33"/>
|
||||||
|
<source>folders.title</source>
|
||||||
|
<translation>Data Folders</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="41"/>
|
||||||
|
<source>folders.songDir</source>
|
||||||
|
<translation>Song jackets</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="62"/>
|
||||||
|
<source>folders.charIconDir</source>
|
||||||
|
<translation>Character icons</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="84"/>
|
||||||
|
<source>options.title</source>
|
||||||
|
<translation>Options</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="170"/>
|
||||||
|
<source>resetButton</source>
|
||||||
|
<translation>Reset</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="211"/>
|
||||||
|
<source>buildButton</source>
|
||||||
|
<translation>Build</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
@ -89,12 +89,12 @@
|
|||||||
<translation>继续</translation>
|
<translation>继续</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../startup/databaseChecker.py" line="115"/>
|
<location filename="../../startup/databaseChecker.py" line="117"/>
|
||||||
<source>dialog.tryInitExistingDatabase</source>
|
<source>dialog.tryInitExistingDatabase</source>
|
||||||
<translation>现有的数据库似乎没有正确初始化,是否尝试再次初始化?</translation>
|
<translation>现有的数据库似乎没有正确初始化,是否尝试再次初始化?</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../startup/databaseChecker.py" line="131"/>
|
<location filename="../../startup/databaseChecker.py" line="133"/>
|
||||||
<source>dialog.confirmNewDatabase</source>
|
<source>dialog.confirmNewDatabase</source>
|
||||||
<translation>数据库文件不存在,是否创建?</translation>
|
<translation>数据库文件不存在,是否创建?</translation>
|
||||||
</message>
|
</message>
|
||||||
@ -695,6 +695,11 @@
|
|||||||
<source>tab.b30</source>
|
<source>tab.b30</source>
|
||||||
<translation>B30</translation>
|
<translation>B30</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcrEntry.ui" line="34"/>
|
||||||
|
<source>tab.buildPHashDatabase</source>
|
||||||
|
<translation>构建 pHash 数据库</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>TabOcr_B30</name>
|
<name>TabOcr_B30</name>
|
||||||
@ -1166,4 +1171,37 @@
|
|||||||
<translation>结果(单曲 PTT)</translation>
|
<translation>结果(单曲 PTT)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>tabOcr_BuildPHashDatabase</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="33"/>
|
||||||
|
<source>folders.title</source>
|
||||||
|
<translation>数据文件夹</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="41"/>
|
||||||
|
<source>folders.songDir</source>
|
||||||
|
<translation>曲封</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="62"/>
|
||||||
|
<source>folders.charIconDir</source>
|
||||||
|
<translation>搭档头像</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="84"/>
|
||||||
|
<source>options.title</source>
|
||||||
|
<translation>选项</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="170"/>
|
||||||
|
<source>resetButton</source>
|
||||||
|
<translation>重置</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/tabs/tabOcr/tabOcr_BuildPHashDatabase.ui" line="211"/>
|
||||||
|
<source>buildButton</source>
|
||||||
|
<translation>构建</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
Reference in New Issue
Block a user