mirror of
https://github.com/283375/arcaea-offline-pyside-ui.git
synced 2025-04-20 17:50:17 +00:00
wip: settings
This commit is contained in:
parent
3390b21800
commit
11c56ba051
40
ui/designer/components/settings/resettableItem.ui
Normal file
40
ui/designer/components/settings/resettableItem.ui
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ResettableItem</class>
|
||||||
|
<widget class="QWidget" name="ResettableItem">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>559</width>
|
||||||
|
<height>42</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string notr="true">ResettableItem</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="resetButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>resetButton</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
45
ui/designer/components/settings/resettableItem_ui.py
Normal file
45
ui/designer/components/settings/resettableItem_ui.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
## Form generated from reading UI file 'resettableItem.ui'
|
||||||
|
##
|
||||||
|
## Created by: Qt User Interface Compiler version 6.5.1
|
||||||
|
##
|
||||||
|
## 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, QHBoxLayout, QPushButton, QSizePolicy,
|
||||||
|
QWidget)
|
||||||
|
|
||||||
|
class Ui_ResettableItem(object):
|
||||||
|
def setupUi(self, ResettableItem):
|
||||||
|
if not ResettableItem.objectName():
|
||||||
|
ResettableItem.setObjectName(u"ResettableItem")
|
||||||
|
ResettableItem.resize(559, 42)
|
||||||
|
ResettableItem.setWindowTitle(u"ResettableItem")
|
||||||
|
self.horizontalLayout = QHBoxLayout(ResettableItem)
|
||||||
|
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||||
|
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.resetButton = QPushButton(ResettableItem)
|
||||||
|
self.resetButton.setObjectName(u"resetButton")
|
||||||
|
|
||||||
|
self.horizontalLayout.addWidget(self.resetButton)
|
||||||
|
|
||||||
|
|
||||||
|
self.retranslateUi(ResettableItem)
|
||||||
|
|
||||||
|
QMetaObject.connectSlotsByName(ResettableItem)
|
||||||
|
# setupUi
|
||||||
|
|
||||||
|
def retranslateUi(self, ResettableItem):
|
||||||
|
self.resetButton.setText(QCoreApplication.translate("ResettableItem", u"resetButton", None))
|
||||||
|
pass
|
||||||
|
# retranslateUi
|
||||||
|
|
@ -13,56 +13,17 @@
|
|||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string notr="true">SettingsDefault</string>
|
<string notr="true">SettingsDefault</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0">
|
||||||
<property name="fieldGrowthPolicy">
|
<item row="1" column="1">
|
||||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
<widget class="DevicesComboBox" name="devicesComboBox">
|
||||||
</property>
|
<property name="minimumSize">
|
||||||
<property name="rowWrapPolicy">
|
<size>
|
||||||
<enum>QFormLayout::DontWrapRows</enum>
|
<width>200</width>
|
||||||
</property>
|
<height>0</height>
|
||||||
<property name="labelAlignment">
|
</size>
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>devicesJsonFile</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="FileSelector" name="devicesJsonFileSelector" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>200</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="devicesJsonFileResetButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>devicesJsonPath.resetButton</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="label_3">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -74,36 +35,12 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>deviceUuid</string>
|
<string>deviceUuid</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="2" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="DevicesComboBox" name="devicesComboBox">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>200</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="deviceUuidResetButton">
|
|
||||||
<property name="text">
|
|
||||||
<string>defaultDevice.resetButton</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
<widget class="QLabel" name="label_4">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
@ -114,15 +51,15 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>tesseractFile</string>
|
<string>tesseractFile</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="FileSelector" name="tesseractFileSelector" native="true">
|
<widget class="FileSelector" name="tesseractFileSelector" native="true">
|
||||||
<property name="sizePolicy">
|
<property name="enabled">
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
<bool>false</bool>
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
@ -132,6 +69,53 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="FileSelector" name="devicesJsonFileSelector" native="true">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>200</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>devicesJsonFile</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2">
|
||||||
|
<widget class="QPushButton" name="deviceUuidResetButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>resetButton</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>knnModelFile</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="2">
|
||||||
|
<widget class="QPushButton" name="devicesJsonFileResetButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>resetButton</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="5" column="1">
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@ -148,6 +132,19 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>siftDatabaseFile</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="FileSelector" name="knnModelFileSelector" native="true"/>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="FileSelector" name="siftDatabaseFileSelector" native="true"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
|
@ -15,8 +15,8 @@ from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
|||||||
QFont, QFontDatabase, QGradient, QIcon,
|
QFont, QFontDatabase, QGradient, QIcon,
|
||||||
QImage, QKeySequence, QLinearGradient, QPainter,
|
QImage, QKeySequence, QLinearGradient, QPainter,
|
||||||
QPalette, QPixmap, QRadialGradient, QTransform)
|
QPalette, QPixmap, QRadialGradient, QTransform)
|
||||||
from PySide6.QtWidgets import (QApplication, QFormLayout, QHBoxLayout, QLabel,
|
from PySide6.QtWidgets import (QApplication, QGridLayout, QLabel, QPushButton,
|
||||||
QPushButton, QSizePolicy, QSpacerItem, QWidget)
|
QSizePolicy, QSpacerItem, QWidget)
|
||||||
|
|
||||||
from ui.implements.components.devicesComboBox import DevicesComboBox
|
from ui.implements.components.devicesComboBox import DevicesComboBox
|
||||||
from ui.implements.components.fileSelector import FileSelector
|
from ui.implements.components.fileSelector import FileSelector
|
||||||
@ -27,92 +27,89 @@ class Ui_SettingsDefault(object):
|
|||||||
SettingsDefault.setObjectName(u"SettingsDefault")
|
SettingsDefault.setObjectName(u"SettingsDefault")
|
||||||
SettingsDefault.resize(682, 493)
|
SettingsDefault.resize(682, 493)
|
||||||
SettingsDefault.setWindowTitle(u"SettingsDefault")
|
SettingsDefault.setWindowTitle(u"SettingsDefault")
|
||||||
self.formLayout = QFormLayout(SettingsDefault)
|
self.gridLayout = QGridLayout(SettingsDefault)
|
||||||
self.formLayout.setObjectName(u"formLayout")
|
self.gridLayout.setObjectName(u"gridLayout")
|
||||||
self.formLayout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
|
self.devicesComboBox = DevicesComboBox(SettingsDefault)
|
||||||
self.formLayout.setRowWrapPolicy(QFormLayout.DontWrapRows)
|
self.devicesComboBox.setObjectName(u"devicesComboBox")
|
||||||
self.formLayout.setLabelAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
|
self.devicesComboBox.setMinimumSize(QSize(200, 0))
|
||||||
self.label_2 = QLabel(SettingsDefault)
|
|
||||||
self.label_2.setObjectName(u"label_2")
|
|
||||||
sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
|
|
||||||
self.label_2.setSizePolicy(sizePolicy)
|
|
||||||
|
|
||||||
self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label_2)
|
self.gridLayout.addWidget(self.devicesComboBox, 1, 1, 1, 1)
|
||||||
|
|
||||||
self.horizontalLayout_2 = QHBoxLayout()
|
|
||||||
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
|
||||||
self.devicesJsonFileSelector = FileSelector(SettingsDefault)
|
|
||||||
self.devicesJsonFileSelector.setObjectName(u"devicesJsonFileSelector")
|
|
||||||
sizePolicy1 = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
|
||||||
sizePolicy1.setHorizontalStretch(0)
|
|
||||||
sizePolicy1.setVerticalStretch(0)
|
|
||||||
sizePolicy1.setHeightForWidth(self.devicesJsonFileSelector.sizePolicy().hasHeightForWidth())
|
|
||||||
self.devicesJsonFileSelector.setSizePolicy(sizePolicy1)
|
|
||||||
self.devicesJsonFileSelector.setMinimumSize(QSize(200, 0))
|
|
||||||
|
|
||||||
self.horizontalLayout_2.addWidget(self.devicesJsonFileSelector)
|
|
||||||
|
|
||||||
self.devicesJsonFileResetButton = QPushButton(SettingsDefault)
|
|
||||||
self.devicesJsonFileResetButton.setObjectName(u"devicesJsonFileResetButton")
|
|
||||||
|
|
||||||
self.horizontalLayout_2.addWidget(self.devicesJsonFileResetButton)
|
|
||||||
|
|
||||||
|
|
||||||
self.formLayout.setLayout(0, QFormLayout.FieldRole, self.horizontalLayout_2)
|
|
||||||
|
|
||||||
self.label_3 = QLabel(SettingsDefault)
|
self.label_3 = QLabel(SettingsDefault)
|
||||||
self.label_3.setObjectName(u"label_3")
|
self.label_3.setObjectName(u"label_3")
|
||||||
|
sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth())
|
sizePolicy.setHeightForWidth(self.label_3.sizePolicy().hasHeightForWidth())
|
||||||
self.label_3.setSizePolicy(sizePolicy)
|
self.label_3.setSizePolicy(sizePolicy)
|
||||||
|
self.label_3.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
|
||||||
|
|
||||||
self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_3)
|
self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
|
||||||
|
|
||||||
self.horizontalLayout = QHBoxLayout()
|
|
||||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
|
||||||
self.devicesComboBox = DevicesComboBox(SettingsDefault)
|
|
||||||
self.devicesComboBox.setObjectName(u"devicesComboBox")
|
|
||||||
sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
|
||||||
sizePolicy2.setHorizontalStretch(0)
|
|
||||||
sizePolicy2.setVerticalStretch(0)
|
|
||||||
sizePolicy2.setHeightForWidth(self.devicesComboBox.sizePolicy().hasHeightForWidth())
|
|
||||||
self.devicesComboBox.setSizePolicy(sizePolicy2)
|
|
||||||
self.devicesComboBox.setMinimumSize(QSize(200, 0))
|
|
||||||
|
|
||||||
self.horizontalLayout.addWidget(self.devicesComboBox)
|
|
||||||
|
|
||||||
self.deviceUuidResetButton = QPushButton(SettingsDefault)
|
|
||||||
self.deviceUuidResetButton.setObjectName(u"deviceUuidResetButton")
|
|
||||||
|
|
||||||
self.horizontalLayout.addWidget(self.deviceUuidResetButton)
|
|
||||||
|
|
||||||
|
|
||||||
self.formLayout.setLayout(1, QFormLayout.FieldRole, self.horizontalLayout)
|
|
||||||
|
|
||||||
self.label_4 = QLabel(SettingsDefault)
|
self.label_4 = QLabel(SettingsDefault)
|
||||||
self.label_4.setObjectName(u"label_4")
|
self.label_4.setObjectName(u"label_4")
|
||||||
sizePolicy.setHeightForWidth(self.label_4.sizePolicy().hasHeightForWidth())
|
sizePolicy.setHeightForWidth(self.label_4.sizePolicy().hasHeightForWidth())
|
||||||
self.label_4.setSizePolicy(sizePolicy)
|
self.label_4.setSizePolicy(sizePolicy)
|
||||||
|
self.label_4.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
|
||||||
|
|
||||||
self.formLayout.setWidget(3, QFormLayout.LabelRole, self.label_4)
|
self.gridLayout.addWidget(self.label_4, 2, 0, 1, 1)
|
||||||
|
|
||||||
self.tesseractFileSelector = FileSelector(SettingsDefault)
|
self.tesseractFileSelector = FileSelector(SettingsDefault)
|
||||||
self.tesseractFileSelector.setObjectName(u"tesseractFileSelector")
|
self.tesseractFileSelector.setObjectName(u"tesseractFileSelector")
|
||||||
sizePolicy3 = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
self.tesseractFileSelector.setEnabled(False)
|
||||||
sizePolicy3.setHorizontalStretch(0)
|
|
||||||
sizePolicy3.setVerticalStretch(0)
|
|
||||||
sizePolicy3.setHeightForWidth(self.tesseractFileSelector.sizePolicy().hasHeightForWidth())
|
|
||||||
self.tesseractFileSelector.setSizePolicy(sizePolicy3)
|
|
||||||
self.tesseractFileSelector.setMinimumSize(QSize(200, 0))
|
self.tesseractFileSelector.setMinimumSize(QSize(200, 0))
|
||||||
|
|
||||||
self.formLayout.setWidget(3, QFormLayout.FieldRole, self.tesseractFileSelector)
|
self.gridLayout.addWidget(self.tesseractFileSelector, 2, 1, 1, 1)
|
||||||
|
|
||||||
|
self.devicesJsonFileSelector = FileSelector(SettingsDefault)
|
||||||
|
self.devicesJsonFileSelector.setObjectName(u"devicesJsonFileSelector")
|
||||||
|
self.devicesJsonFileSelector.setMinimumSize(QSize(200, 0))
|
||||||
|
|
||||||
|
self.gridLayout.addWidget(self.devicesJsonFileSelector, 0, 1, 1, 1)
|
||||||
|
|
||||||
|
self.label_2 = QLabel(SettingsDefault)
|
||||||
|
self.label_2.setObjectName(u"label_2")
|
||||||
|
sizePolicy.setHeightForWidth(self.label_2.sizePolicy().hasHeightForWidth())
|
||||||
|
self.label_2.setSizePolicy(sizePolicy)
|
||||||
|
self.label_2.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
|
||||||
|
|
||||||
|
self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1)
|
||||||
|
|
||||||
|
self.deviceUuidResetButton = QPushButton(SettingsDefault)
|
||||||
|
self.deviceUuidResetButton.setObjectName(u"deviceUuidResetButton")
|
||||||
|
|
||||||
|
self.gridLayout.addWidget(self.deviceUuidResetButton, 1, 2, 1, 1)
|
||||||
|
|
||||||
|
self.label = QLabel(SettingsDefault)
|
||||||
|
self.label.setObjectName(u"label")
|
||||||
|
|
||||||
|
self.gridLayout.addWidget(self.label, 3, 0, 1, 1)
|
||||||
|
|
||||||
|
self.devicesJsonFileResetButton = QPushButton(SettingsDefault)
|
||||||
|
self.devicesJsonFileResetButton.setObjectName(u"devicesJsonFileResetButton")
|
||||||
|
|
||||||
|
self.gridLayout.addWidget(self.devicesJsonFileResetButton, 0, 2, 1, 1)
|
||||||
|
|
||||||
self.verticalSpacer = QSpacerItem(20, 500000, QSizePolicy.Minimum, QSizePolicy.Expanding)
|
self.verticalSpacer = QSpacerItem(20, 500000, QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||||||
|
|
||||||
self.formLayout.setItem(5, QFormLayout.FieldRole, self.verticalSpacer)
|
self.gridLayout.addItem(self.verticalSpacer, 5, 1, 1, 1)
|
||||||
|
|
||||||
|
self.label_5 = QLabel(SettingsDefault)
|
||||||
|
self.label_5.setObjectName(u"label_5")
|
||||||
|
|
||||||
|
self.gridLayout.addWidget(self.label_5, 4, 0, 1, 1)
|
||||||
|
|
||||||
|
self.knnModelFileSelector = FileSelector(SettingsDefault)
|
||||||
|
self.knnModelFileSelector.setObjectName(u"knnModelFileSelector")
|
||||||
|
|
||||||
|
self.gridLayout.addWidget(self.knnModelFileSelector, 3, 1, 1, 1)
|
||||||
|
|
||||||
|
self.siftDatabaseFileSelector = FileSelector(SettingsDefault)
|
||||||
|
self.siftDatabaseFileSelector.setObjectName(u"siftDatabaseFileSelector")
|
||||||
|
|
||||||
|
self.gridLayout.addWidget(self.siftDatabaseFileSelector, 4, 1, 1, 1)
|
||||||
|
|
||||||
|
self.gridLayout.setColumnStretch(1, 1)
|
||||||
|
|
||||||
self.retranslateUi(SettingsDefault)
|
self.retranslateUi(SettingsDefault)
|
||||||
|
|
||||||
@ -120,11 +117,13 @@ class Ui_SettingsDefault(object):
|
|||||||
# setupUi
|
# setupUi
|
||||||
|
|
||||||
def retranslateUi(self, SettingsDefault):
|
def retranslateUi(self, SettingsDefault):
|
||||||
self.label_2.setText(QCoreApplication.translate("SettingsDefault", u"devicesJsonFile", None))
|
|
||||||
self.devicesJsonFileResetButton.setText(QCoreApplication.translate("SettingsDefault", u"devicesJsonPath.resetButton", None))
|
|
||||||
self.label_3.setText(QCoreApplication.translate("SettingsDefault", u"deviceUuid", None))
|
self.label_3.setText(QCoreApplication.translate("SettingsDefault", u"deviceUuid", None))
|
||||||
self.deviceUuidResetButton.setText(QCoreApplication.translate("SettingsDefault", u"defaultDevice.resetButton", None))
|
|
||||||
self.label_4.setText(QCoreApplication.translate("SettingsDefault", u"tesseractFile", None))
|
self.label_4.setText(QCoreApplication.translate("SettingsDefault", u"tesseractFile", None))
|
||||||
|
self.label_2.setText(QCoreApplication.translate("SettingsDefault", u"devicesJsonFile", None))
|
||||||
|
self.deviceUuidResetButton.setText(QCoreApplication.translate("SettingsDefault", u"resetButton", None))
|
||||||
|
self.label.setText(QCoreApplication.translate("SettingsDefault", u"knnModelFile", None))
|
||||||
|
self.devicesJsonFileResetButton.setText(QCoreApplication.translate("SettingsDefault", u"resetButton", None))
|
||||||
|
self.label_5.setText(QCoreApplication.translate("SettingsDefault", u"siftDatabaseFile", None))
|
||||||
pass
|
pass
|
||||||
# retranslateUi
|
# retranslateUi
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ class OcrQueueModel(QAbstractListModel):
|
|||||||
index = self.index(row, 0)
|
index = self.index(row, 0)
|
||||||
imagePath: str = index.data(self.ImagePathRole)
|
imagePath: str = index.data(self.ImagePathRole)
|
||||||
qImage: QImage = index.data(self.ImageQImageRole)
|
qImage: QImage = index.data(self.ImageQImageRole)
|
||||||
print(row, result)
|
logger.info(f"update request: {result}@row{row}")
|
||||||
processOcrResultFunc = index.data(self.ProcessOcrResultFuncRole)
|
processOcrResultFunc = index.data(self.ProcessOcrResultFuncRole)
|
||||||
|
|
||||||
chart, scoreInsert = processOcrResultFunc(imagePath, qImage, result)
|
chart, scoreInsert = processOcrResultFunc(imagePath, qImage, result)
|
||||||
|
@ -5,6 +5,8 @@ __all__ = [
|
|||||||
"DEVICES_JSON_FILE",
|
"DEVICES_JSON_FILE",
|
||||||
"DEVICE_UUID",
|
"DEVICE_UUID",
|
||||||
"TESSERACT_FILE",
|
"TESSERACT_FILE",
|
||||||
|
"KNN_MODEL_FILE",
|
||||||
|
"SIFT_DATABASE_FILE",
|
||||||
"Settings",
|
"Settings",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -13,6 +15,8 @@ DATABASE_PATH = "General/DatabasePath"
|
|||||||
DEVICES_JSON_FILE = "Ocr/DevicesJsonFile"
|
DEVICES_JSON_FILE = "Ocr/DevicesJsonFile"
|
||||||
DEVICE_UUID = "Ocr/DeviceUuid"
|
DEVICE_UUID = "Ocr/DeviceUuid"
|
||||||
TESSERACT_FILE = "Ocr/TesseractFile"
|
TESSERACT_FILE = "Ocr/TesseractFile"
|
||||||
|
KNN_MODEL_FILE = "Ocr/KnnModelFile"
|
||||||
|
SIFT_DATABASE_FILE = "Ocr/SiftDatabaseFile"
|
||||||
|
|
||||||
|
|
||||||
class Settings(QSettings):
|
class Settings(QSettings):
|
||||||
@ -55,3 +59,25 @@ class Settings(QSettings):
|
|||||||
def resetTesseractPath(self):
|
def resetTesseractPath(self):
|
||||||
self.setValue(TESSERACT_FILE, None)
|
self.setValue(TESSERACT_FILE, None)
|
||||||
self.sync()
|
self.sync()
|
||||||
|
|
||||||
|
def knnModelFile(self) -> str | None:
|
||||||
|
return self.value(KNN_MODEL_FILE, None, str)
|
||||||
|
|
||||||
|
def setKnnModelFile(self, path: str):
|
||||||
|
self.setValue(KNN_MODEL_FILE, path)
|
||||||
|
self.sync()
|
||||||
|
|
||||||
|
def resetKnnModelFile(self):
|
||||||
|
self.setValue(KNN_MODEL_FILE, None)
|
||||||
|
self.sync()
|
||||||
|
|
||||||
|
def siftDatabaseFile(self) -> str | None:
|
||||||
|
return self.value(SIFT_DATABASE_FILE, None, str)
|
||||||
|
|
||||||
|
def setSiftDatabaseFile(self, path: str):
|
||||||
|
self.setValue(SIFT_DATABASE_FILE, path)
|
||||||
|
self.sync()
|
||||||
|
|
||||||
|
def resetSiftDatabaseFile(self):
|
||||||
|
self.setValue(SIFT_DATABASE_FILE, None)
|
||||||
|
self.sync()
|
||||||
|
19
ui/implements/components/settings/resettableItem.py
Normal file
19
ui/implements/components/settings/resettableItem.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
from PySide6.QtWidgets import QSizePolicy, QWidget
|
||||||
|
|
||||||
|
from ui.designer.components.settings.resettableItem_ui import Ui_ResettableItem
|
||||||
|
|
||||||
|
|
||||||
|
class ResettableItem(Ui_ResettableItem, QWidget):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setupUi(self)
|
||||||
|
|
||||||
|
def setWidget(self, widget: QWidget):
|
||||||
|
firstItem = self.horizontalLayout.itemAt(0)
|
||||||
|
if firstItem.objectName() != "resetButton":
|
||||||
|
self.horizontalLayout.removeItem(firstItem)
|
||||||
|
|
||||||
|
sizePolicy = widget.sizePolicy()
|
||||||
|
sizePolicy.setHorizontalPolicy(QSizePolicy.Policy.Expanding)
|
||||||
|
widget.setSizePolicy(sizePolicy)
|
||||||
|
self.horizontalLayout.insertWidget(0, widget)
|
@ -1,4 +1,5 @@
|
|||||||
from arcaea_offline.database import Database
|
import logging
|
||||||
|
|
||||||
from PySide6.QtCore import Slot
|
from PySide6.QtCore import Slot
|
||||||
from PySide6.QtWidgets import QWidget
|
from PySide6.QtWidgets import QWidget
|
||||||
|
|
||||||
@ -6,6 +7,8 @@ from ui.designer.settings.settingsDefault_ui import Ui_SettingsDefault
|
|||||||
from ui.extends.ocr import load_devices_json
|
from ui.extends.ocr import load_devices_json
|
||||||
from ui.extends.settings import *
|
from ui.extends.settings import *
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class SettingsDefault(Ui_SettingsDefault, QWidget):
|
class SettingsDefault(Ui_SettingsDefault, QWidget):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
@ -29,6 +32,12 @@ class SettingsDefault(Ui_SettingsDefault, QWidget):
|
|||||||
self.tesseractFileSelector.accepted.connect(
|
self.tesseractFileSelector.accepted.connect(
|
||||||
self.on_tesseractFileSelector_accepted
|
self.on_tesseractFileSelector_accepted
|
||||||
)
|
)
|
||||||
|
self.knnModelFileSelector.accepted.connect(
|
||||||
|
self.on_knnModelFileSelector_accepted
|
||||||
|
)
|
||||||
|
self.siftDatabaseFileSelector.accepted.connect(
|
||||||
|
self.on_siftDatabaseFileSelector_accepted
|
||||||
|
)
|
||||||
|
|
||||||
def setDevicesJsonFile(self):
|
def setDevicesJsonFile(self):
|
||||||
try:
|
try:
|
||||||
@ -37,7 +46,7 @@ class SettingsDefault(Ui_SettingsDefault, QWidget):
|
|||||||
assert isinstance(devices, list)
|
assert isinstance(devices, list)
|
||||||
self.settings.setDevicesJsonFile(filename)
|
self.settings.setDevicesJsonFile(filename)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
logger.exception("set deviceJsonFile error")
|
||||||
# QMessageBox
|
# QMessageBox
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -71,3 +80,17 @@ class SettingsDefault(Ui_SettingsDefault, QWidget):
|
|||||||
|
|
||||||
def on_tesseractFileSelector_accepted(self):
|
def on_tesseractFileSelector_accepted(self):
|
||||||
self.setTesseractFile()
|
self.setTesseractFile()
|
||||||
|
|
||||||
|
def setKnnModelFile(self):
|
||||||
|
file = self.knnModelFileSelector.selectedFiles()[0]
|
||||||
|
self.settings.setKnnModelFile(file)
|
||||||
|
|
||||||
|
def on_knnModelFileSelector_accepted(self):
|
||||||
|
self.setKnnModelFile()
|
||||||
|
|
||||||
|
def setSiftDatabaseFile(self):
|
||||||
|
file = self.siftDatabaseFileSelector.selectedFiles()[0]
|
||||||
|
self.settings.setSiftDatabaseFile(file)
|
||||||
|
|
||||||
|
def on_siftDatabaseFileSelector_accepted(self):
|
||||||
|
self.setSiftDatabaseFile()
|
||||||
|
@ -12,6 +12,7 @@ from PySide6.QtWidgets import QWidget
|
|||||||
|
|
||||||
from ui.designer.tabs.tabOcr.tabOcr_B30_ui import Ui_TabOcr_B30
|
from ui.designer.tabs.tabOcr.tabOcr_B30_ui import Ui_TabOcr_B30
|
||||||
from ui.extends.components.ocrQueue import OcrQueueModel
|
from ui.extends.components.ocrQueue import OcrQueueModel
|
||||||
|
from ui.extends.settings import Settings
|
||||||
from ui.extends.shared.cv2_utils import cv2BgrMatToQImage, qImageToCvMatBgr
|
from ui.extends.shared.cv2_utils import cv2BgrMatToQImage, qImageToCvMatBgr
|
||||||
from ui.extends.tabs.tabOcr.tabOcr_B30 import (
|
from ui.extends.tabs.tabOcr.tabOcr_B30 import (
|
||||||
ChieriV4OcrRunnable,
|
ChieriV4OcrRunnable,
|
||||||
@ -54,6 +55,11 @@ class TabOcr_B30(Ui_TabOcr_B30, QWidget):
|
|||||||
|
|
||||||
self.tryPrepareOcr.connect(self.prepareOcr)
|
self.tryPrepareOcr.connect(self.prepareOcr)
|
||||||
|
|
||||||
|
settings = Settings()
|
||||||
|
logger.info("Applying default settings...")
|
||||||
|
self.knnModelSelector.selectFile(settings.knnModelFile())
|
||||||
|
self.siftDatabaseSelector.selectFile(settings.siftDatabaseFile())
|
||||||
|
|
||||||
self.ocrQueueModel = OcrQueueModel(self)
|
self.ocrQueueModel = OcrQueueModel(self)
|
||||||
self.ocrQueue.setModel(self.ocrQueueModel)
|
self.ocrQueue.setModel(self.ocrQueueModel)
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
import pytesseract
|
import pytesseract
|
||||||
|
|
||||||
@ -16,6 +18,8 @@ from ui.extends.tabs.tabOcr.tabOcr_Device import (
|
|||||||
TabDeviceV2OcrRunnable,
|
TabDeviceV2OcrRunnable,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class TabOcr_Device(Ui_TabOcr_Device, QWidget):
|
class TabOcr_Device(Ui_TabOcr_Device, QWidget):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
@ -35,9 +39,12 @@ class TabOcr_Device(Ui_TabOcr_Device, QWidget):
|
|||||||
self.siftDatabaseSelector.filesSelected.connect(self.siftDatabaseFileSelected)
|
self.siftDatabaseSelector.filesSelected.connect(self.siftDatabaseFileSelected)
|
||||||
|
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
|
logger.info("Applying default settings...")
|
||||||
self.deviceFileSelector.selectFile(settings.devicesJsonFile())
|
self.deviceFileSelector.selectFile(settings.devicesJsonFile())
|
||||||
self.tesseractFileSelector.selectFile(settings.tesseractPath())
|
self.tesseractFileSelector.selectFile(settings.tesseractPath())
|
||||||
self.deviceComboBox.selectDevice(settings.deviceUuid())
|
self.deviceComboBox.selectDevice(settings.deviceUuid())
|
||||||
|
self.knnModelSelector.selectFile(settings.knnModelFile())
|
||||||
|
self.siftDatabaseSelector.selectFile(settings.siftDatabaseFile())
|
||||||
|
|
||||||
self.ocrQueueModel = OcrQueueModel(self)
|
self.ocrQueueModel = OcrQueueModel(self)
|
||||||
self.ocrQueue.setModel(self.ocrQueueModel)
|
self.ocrQueue.setModel(self.ocrQueueModel)
|
||||||
|
@ -280,6 +280,14 @@ validation</translation>
|
|||||||
<translation>Score</translation>
|
<translation>Score</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>ResettableItem</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/components/settings/resettableItem.ui" line="32"/>
|
||||||
|
<source>resetButton</source>
|
||||||
|
<translation>Reset</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ScoreEditor</name>
|
<name>ScoreEditor</name>
|
||||||
<message>
|
<message>
|
||||||
@ -357,29 +365,35 @@ validation</translation>
|
|||||||
<context>
|
<context>
|
||||||
<name>SettingsDefault</name>
|
<name>SettingsDefault</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../designer/settings/settingsDefault.ui" line="35"/>
|
<location filename="../../designer/settings/settingsDefault.ui" line="91"/>
|
||||||
<source>devicesJsonFile</source>
|
<source>devicesJsonFile</source>
|
||||||
<translation>Default devices.json</translation>
|
<translation>Default devices.json</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../designer/settings/settingsDefault.ui" line="75"/>
|
<location filename="../../designer/settings/settingsDefault.ui" line="36"/>
|
||||||
<source>deviceUuid</source>
|
<source>deviceUuid</source>
|
||||||
<translation>Default Device</translation>
|
<translation>Default Device</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../designer/settings/settingsDefault.ui" line="115"/>
|
<location filename="../../designer/settings/settingsDefault.ui" line="52"/>
|
||||||
<source>tesseractFile</source>
|
<source>tesseractFile</source>
|
||||||
<translation>tesseract Path</translation>
|
<translation>tesseract Path</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../designer/settings/settingsDefault.ui" line="100"/>
|
<location filename="../../designer/settings/settingsDefault.ui" line="101"/>
|
||||||
<source>defaultDevice.resetButton</source>
|
<location filename="../../designer/settings/settingsDefault.ui" line="115"/>
|
||||||
<translation type="unfinished"></translation>
|
<source>resetButton</source>
|
||||||
|
<translation>Reset</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../designer/settings/settingsDefault.ui" line="60"/>
|
<location filename="../../designer/settings/settingsDefault.ui" line="108"/>
|
||||||
<source>devicesJsonPath.resetButton</source>
|
<source>knnModelFile</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Default KNearest Model</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/settings/settingsDefault.ui" line="138"/>
|
||||||
|
<source>siftDatabaseFile</source>
|
||||||
|
<translation>Default SIFT Database File</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -279,6 +279,14 @@
|
|||||||
<translation>分数</translation>
|
<translation>分数</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>ResettableItem</name>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/components/settings/resettableItem.ui" line="32"/>
|
||||||
|
<source>resetButton</source>
|
||||||
|
<translation>重置</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ScoreEditor</name>
|
<name>ScoreEditor</name>
|
||||||
<message>
|
<message>
|
||||||
@ -356,29 +364,35 @@
|
|||||||
<context>
|
<context>
|
||||||
<name>SettingsDefault</name>
|
<name>SettingsDefault</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../designer/settings/settingsDefault.ui" line="35"/>
|
<location filename="../../designer/settings/settingsDefault.ui" line="91"/>
|
||||||
<source>devicesJsonFile</source>
|
<source>devicesJsonFile</source>
|
||||||
<translation>默认设备文件</translation>
|
<translation>默认设备文件</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../designer/settings/settingsDefault.ui" line="75"/>
|
<location filename="../../designer/settings/settingsDefault.ui" line="36"/>
|
||||||
<source>deviceUuid</source>
|
<source>deviceUuid</source>
|
||||||
<translation>默认设备</translation>
|
<translation>默认设备</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../designer/settings/settingsDefault.ui" line="115"/>
|
<location filename="../../designer/settings/settingsDefault.ui" line="52"/>
|
||||||
<source>tesseractFile</source>
|
<source>tesseractFile</source>
|
||||||
<translation>tesseract 路径</translation>
|
<translation>tesseract 路径</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../designer/settings/settingsDefault.ui" line="100"/>
|
<location filename="../../designer/settings/settingsDefault.ui" line="101"/>
|
||||||
<source>defaultDevice.resetButton</source>
|
<location filename="../../designer/settings/settingsDefault.ui" line="115"/>
|
||||||
<translation type="unfinished"></translation>
|
<source>resetButton</source>
|
||||||
|
<translation>重置</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../designer/settings/settingsDefault.ui" line="60"/>
|
<location filename="../../designer/settings/settingsDefault.ui" line="108"/>
|
||||||
<source>devicesJsonPath.resetButton</source>
|
<source>knnModelFile</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>默认 KNearest 模型</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../designer/settings/settingsDefault.ui" line="138"/>
|
||||||
|
<source>siftDatabaseFile</source>
|
||||||
|
<translation>默认 SIFT 特征值数据库</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user