mirror of
https://github.com/283375/arcaea-offline-ocr-model.git
synced 2025-04-04 14:10:18 +00:00
init
This commit is contained in:
commit
e84f2bec81
164
.gitignore
vendored
Normal file
164
.gitignore
vendored
Normal file
@ -0,0 +1,164 @@
|
||||
__debug*.py
|
||||
/projects
|
||||
/.vscode
|
||||
|
||||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.nox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*.cover
|
||||
*.py,cover
|
||||
.hypothesis/
|
||||
.pytest_cache/
|
||||
cover/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
db.sqlite3
|
||||
db.sqlite3-journal
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
.pybuilder/
|
||||
target/
|
||||
|
||||
# Jupyter Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# IPython
|
||||
profile_default/
|
||||
ipython_config.py
|
||||
|
||||
# pyenv
|
||||
# For a library or package, you might want to ignore these files since the code is
|
||||
# intended to run in multiple environments; otherwise, check them in:
|
||||
# .python-version
|
||||
|
||||
# pipenv
|
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
||||
# install all needed dependencies.
|
||||
#Pipfile.lock
|
||||
|
||||
# poetry
|
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
||||
# commonly ignored for libraries.
|
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
||||
#poetry.lock
|
||||
|
||||
# pdm
|
||||
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
|
||||
# Celery stuff
|
||||
celerybeat-schedule
|
||||
celerybeat.pid
|
||||
|
||||
# SageMath parsed files
|
||||
*.sage.py
|
||||
|
||||
# Environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
.spyproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
||||
|
||||
# mkdocs documentation
|
||||
/site
|
||||
|
||||
# mypy
|
||||
.mypy_cache/
|
||||
.dmypy.json
|
||||
dmypy.json
|
||||
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# pytype static type analyzer
|
||||
.pytype/
|
||||
|
||||
# Cython debug symbols
|
||||
cython_debug/
|
||||
|
||||
# PyCharm
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
211
project.py
Normal file
211
project.py
Normal file
@ -0,0 +1,211 @@
|
||||
import importlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
from copy import deepcopy
|
||||
from functools import cached_property
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
from hashlib import md5
|
||||
from io import BytesIO
|
||||
|
||||
import cv2
|
||||
|
||||
PROJECTS_ROOT_PATH = Path("projects")
|
||||
ACCEPT_EXTS = [".jpg", ".png"]
|
||||
|
||||
|
||||
class Project:
|
||||
path: Path
|
||||
|
||||
def __init__(self, path: Path):
|
||||
self.path = path
|
||||
self._tagValueDict = {}
|
||||
with open(self.path / "project.json", "r", encoding="utf-8") as jf:
|
||||
projectJson = json.loads(jf.read())
|
||||
self._tagValueDict: dict[str, Any] = projectJson["tagValueMap"]
|
||||
self.name = projectJson.get("name", self.path.name)
|
||||
self._tags = list(self._tagValueDict.keys())
|
||||
self._values = list(self._tagValueDict.values())
|
||||
|
||||
def __repr__(self):
|
||||
return f"Project(path={repr(self.path)})"
|
||||
|
||||
@cached_property
|
||||
def tags(self):
|
||||
return deepcopy(self._tags)
|
||||
|
||||
@cached_property
|
||||
def values(self):
|
||||
return deepcopy(self.values)
|
||||
|
||||
@cached_property
|
||||
def tagValueMap(self):
|
||||
return deepcopy(self._tagValueDict)
|
||||
|
||||
@cached_property
|
||||
def tagsReExp(self):
|
||||
tagsDivided = "|".join(str(tag) for tag in self.tags)
|
||||
return re.compile(f"^({tagsDivided})\\^")
|
||||
|
||||
@cached_property
|
||||
def sourcesPath(self):
|
||||
return self.path / "sources"
|
||||
|
||||
@cached_property
|
||||
def samplesPath(self):
|
||||
return self.path / "samples"
|
||||
|
||||
@cached_property
|
||||
def samplesUnclassifiedPath(self):
|
||||
return self.samplesPath / "unclassified"
|
||||
|
||||
@cached_property
|
||||
def samplesClassifiedPath(self):
|
||||
return self.samplesPath / "classified"
|
||||
|
||||
@cached_property
|
||||
def samplesIgnoredPath(self):
|
||||
return self.samplesPath / "ignored"
|
||||
|
||||
def createFolders(self):
|
||||
folders = [
|
||||
self.sourcesPath,
|
||||
self.samplesClassifiedPath,
|
||||
self.samplesUnclassifiedPath,
|
||||
self.samplesIgnoredPath,
|
||||
]
|
||||
|
||||
for folder in folders:
|
||||
folder.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
def listPathFiles(self, path: Path, acceptSuffixes: list[str] = ACCEPT_EXTS):
|
||||
return [p for p in path.glob("**/*") if p.suffix in acceptSuffixes]
|
||||
|
||||
@property
|
||||
def sources(self):
|
||||
return self.listPathFiles(self.sourcesPath)
|
||||
|
||||
@property
|
||||
def samples(self):
|
||||
return self.listPathFiles(self.samplesPath)
|
||||
|
||||
@property
|
||||
def samplesUnclassified(self):
|
||||
return self.listPathFiles(self.samplesUnclassifiedPath)
|
||||
|
||||
@property
|
||||
def samplesClassified(self):
|
||||
return self.listPathFiles(self.samplesClassifiedPath)
|
||||
|
||||
@property
|
||||
def samplesIgnored(self):
|
||||
return self.listPathFiles(self.samplesIgnoredPath)
|
||||
|
||||
def samplesByTag(self, tag: str):
|
||||
if tag not in self.tags:
|
||||
raise ValueError(f'Unknown tag "{tag}"')
|
||||
|
||||
samples = self.samples
|
||||
return [p for p in samples if p.stem.startswith(f"{tag}^")]
|
||||
|
||||
def extractYield(self):
|
||||
cwdPath = Path(os.getcwd())
|
||||
importParts = [
|
||||
*self.path.resolve().relative_to(cwdPath.resolve()).parts,
|
||||
"extract",
|
||||
]
|
||||
importName = ".".join(importParts)
|
||||
projectExtractModule = importlib.import_module(importName)
|
||||
getSamples = projectExtractModule.getSamples
|
||||
assert callable(getSamples)
|
||||
|
||||
extractLogger = logging.getLogger(
|
||||
f"extract-{self.name}-{int(time.time() * 1000)}"
|
||||
)
|
||||
|
||||
extractLogger.info("Reading existing samples MD5...")
|
||||
# existingSamplesMd5 = [
|
||||
# self.getSampleOriginalFileName(sample).split(".")[0] for sample in samples
|
||||
# ]
|
||||
existingSamplesMd5 = []
|
||||
for sample in self.samples:
|
||||
with open(sample, "rb") as sf:
|
||||
existingSamplesMd5.append(md5(sf.read()).hexdigest())
|
||||
|
||||
sources = self.sources
|
||||
sourcesNum = len(sources)
|
||||
for i, source in enumerate(sources):
|
||||
try:
|
||||
extractLogger.info(f"Extracting {source.resolve()}")
|
||||
samples = getSamples(source)
|
||||
for sample in samples:
|
||||
success, sampleBuffer = cv2.imencode(".jpg", sample)
|
||||
if not success:
|
||||
extractLogger.warning(
|
||||
f"cv2 cannot encode {sampleMd5} from {source.name}, skipping"
|
||||
)
|
||||
continue
|
||||
|
||||
sampleMd5 = md5(sampleBuffer).hexdigest()
|
||||
if sampleMd5 in existingSamplesMd5:
|
||||
extractLogger.debug(f"{sampleMd5} from {source.name} skipped")
|
||||
continue
|
||||
|
||||
extractLogger.info(f"{sampleMd5} <- {source.name}")
|
||||
sampleSavePath = self.samplesUnclassifiedPath / f"{sampleMd5}.jpg"
|
||||
with open(sampleSavePath, "wb") as sf:
|
||||
sf.write(sampleBuffer)
|
||||
existingSamplesMd5.append(sampleMd5)
|
||||
except Exception:
|
||||
extractLogger.exception(f"Error extracting {source.resolve()}")
|
||||
finally:
|
||||
yield (source, i, sourcesNum)
|
||||
|
||||
def extract(self):
|
||||
list(self.extractYield())
|
||||
|
||||
def getSampleOriginalFileName(self, sample: Path):
|
||||
return self.tagsReExp.sub("", sample.name)
|
||||
|
||||
def classify(self, sample: Path, tag: str):
|
||||
if tag not in self.tags:
|
||||
raise ValueError(f'Unknown tag "{tag}"')
|
||||
|
||||
originalFileName = self.getSampleOriginalFileName(sample)
|
||||
classifiedFileName = f"{tag}^{originalFileName}"
|
||||
return sample.rename(self.samplesClassifiedPath / classifiedFileName)
|
||||
|
||||
def unclassify(self, sample: Path):
|
||||
originalFileName = self.getSampleOriginalFileName(sample)
|
||||
return sample.rename(self.samplesUnclassifiedPath / originalFileName)
|
||||
|
||||
def ignore(self, sample: Path):
|
||||
originalFileName = self.getSampleOriginalFileName(sample)
|
||||
return sample.rename(self.samplesIgnoredPath / originalFileName)
|
||||
|
||||
|
||||
class Projects:
|
||||
def __init__(self, rootFolderPath=PROJECTS_ROOT_PATH):
|
||||
self.rootFolderPath = rootFolderPath
|
||||
self.projects: list[Project] = []
|
||||
self.detectProjects()
|
||||
|
||||
def detectProjects(self):
|
||||
self.projects.clear()
|
||||
|
||||
folders = [p for p in self.rootFolderPath.iterdir() if p.is_dir()]
|
||||
for folder in folders:
|
||||
if not (folder / "project.json").exists():
|
||||
continue
|
||||
project = Project(folder)
|
||||
if not (
|
||||
project.sourcesPath.exists()
|
||||
and project.samplesClassifiedPath.exists()
|
||||
and project.samplesUnclassifiedPath.exists()
|
||||
and project.samplesIgnoredPath.exists()
|
||||
):
|
||||
continue
|
||||
self.projects.append(project)
|
11
pyproject.toml
Normal file
11
pyproject.toml
Normal file
@ -0,0 +1,11 @@
|
||||
[tool.black]
|
||||
force-exclude = '''
|
||||
(
|
||||
.*_rc.py
|
||||
| .*_ui.py
|
||||
)
|
||||
'''
|
||||
|
||||
[tool.isort]
|
||||
profile = "black"
|
||||
extend_skip_glob = ["*_rc.py", "*_ui.py"]
|
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
||||
tqdm==4.66.1
|
||||
PySide6==6.5.2
|
0
ui/__init__.py
Normal file
0
ui/__init__.py
Normal file
19
ui/components/logItemDetails.ui
Normal file
19
ui/components/logItemDetails.ui
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>LogItemDetails</class>
|
||||
<widget class="QWidget" name="LogItemDetails">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>603</width>
|
||||
<height>469</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">LogItemDetails</string>
|
||||
</property>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
35
ui/components/logItemDetails_ui.py
Normal file
35
ui/components/logItemDetails_ui.py
Normal file
@ -0,0 +1,35 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'logItemDetails.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, QSizePolicy, QWidget)
|
||||
|
||||
class Ui_LogItemDetails(object):
|
||||
def setupUi(self, LogItemDetails):
|
||||
if not LogItemDetails.objectName():
|
||||
LogItemDetails.setObjectName(u"LogItemDetails")
|
||||
LogItemDetails.resize(603, 469)
|
||||
LogItemDetails.setWindowTitle(u"LogItemDetails")
|
||||
|
||||
self.retranslateUi(LogItemDetails)
|
||||
|
||||
QMetaObject.connectSlotsByName(LogItemDetails)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, LogItemDetails):
|
||||
pass
|
||||
# retranslateUi
|
||||
|
94
ui/components/logViewer.ui
Normal file
94
ui/components/logViewer.ui
Normal file
@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>LogViewer</class>
|
||||
<widget class="QWidget" name="LogViewer">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>597</width>
|
||||
<height>443</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">LogViewer</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1,0,0,1">
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Group</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QComboBox" name="groupComboBox"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="levelLabel">
|
||||
<property name="text">
|
||||
<string>INFO</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSlider" name="levelSlider">
|
||||
<property name="maximum">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="tracking">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>25</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="logTreeView"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
88
ui/components/logViewer_ui.py
Normal file
88
ui/components/logViewer_ui.py
Normal file
@ -0,0 +1,88 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'logViewer.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, QComboBox, QFrame, QGridLayout,
|
||||
QHeaderView, QLabel, QSizePolicy, QSlider,
|
||||
QSpacerItem, QTreeView, QVBoxLayout, QWidget)
|
||||
|
||||
class Ui_LogViewer(object):
|
||||
def setupUi(self, LogViewer):
|
||||
if not LogViewer.objectName():
|
||||
LogViewer.setObjectName(u"LogViewer")
|
||||
LogViewer.resize(597, 443)
|
||||
LogViewer.setWindowTitle(u"LogViewer")
|
||||
self.verticalLayout = QVBoxLayout(LogViewer)
|
||||
self.verticalLayout.setObjectName(u"verticalLayout")
|
||||
self.frame = QFrame(LogViewer)
|
||||
self.frame.setObjectName(u"frame")
|
||||
self.frame.setFrameShape(QFrame.StyledPanel)
|
||||
self.frame.setFrameShadow(QFrame.Raised)
|
||||
self.gridLayout = QGridLayout(self.frame)
|
||||
self.gridLayout.setObjectName(u"gridLayout")
|
||||
self.label = QLabel(self.frame)
|
||||
self.label.setObjectName(u"label")
|
||||
|
||||
self.gridLayout.addWidget(self.label, 0, 3, 1, 1)
|
||||
|
||||
self.groupComboBox = QComboBox(self.frame)
|
||||
self.groupComboBox.setObjectName(u"groupComboBox")
|
||||
|
||||
self.gridLayout.addWidget(self.groupComboBox, 0, 4, 1, 1)
|
||||
|
||||
self.levelLabel = QLabel(self.frame)
|
||||
self.levelLabel.setObjectName(u"levelLabel")
|
||||
|
||||
self.gridLayout.addWidget(self.levelLabel, 0, 0, 1, 1)
|
||||
|
||||
self.levelSlider = QSlider(self.frame)
|
||||
self.levelSlider.setObjectName(u"levelSlider")
|
||||
self.levelSlider.setMaximum(5)
|
||||
self.levelSlider.setSingleStep(1)
|
||||
self.levelSlider.setPageStep(1)
|
||||
self.levelSlider.setValue(2)
|
||||
self.levelSlider.setTracking(True)
|
||||
self.levelSlider.setOrientation(Qt.Horizontal)
|
||||
self.levelSlider.setTickPosition(QSlider.TicksBelow)
|
||||
|
||||
self.gridLayout.addWidget(self.levelSlider, 0, 1, 1, 1)
|
||||
|
||||
self.horizontalSpacer = QSpacerItem(25, 10, QSizePolicy.Preferred, QSizePolicy.Minimum)
|
||||
|
||||
self.gridLayout.addItem(self.horizontalSpacer, 0, 2, 1, 1)
|
||||
|
||||
self.gridLayout.setColumnStretch(1, 1)
|
||||
self.gridLayout.setColumnStretch(4, 1)
|
||||
|
||||
self.verticalLayout.addWidget(self.frame)
|
||||
|
||||
self.logTreeView = QTreeView(LogViewer)
|
||||
self.logTreeView.setObjectName(u"logTreeView")
|
||||
|
||||
self.verticalLayout.addWidget(self.logTreeView)
|
||||
|
||||
|
||||
self.retranslateUi(LogViewer)
|
||||
|
||||
QMetaObject.connectSlotsByName(LogViewer)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, LogViewer):
|
||||
self.label.setText(QCoreApplication.translate("LogViewer", u"Group", None))
|
||||
self.levelLabel.setText(QCoreApplication.translate("LogViewer", u"INFO", None))
|
||||
pass
|
||||
# retranslateUi
|
||||
|
33
ui/components/projectEntry.py
Normal file
33
ui/components/projectEntry.py
Normal file
@ -0,0 +1,33 @@
|
||||
from PySide6.QtWidgets import QWidget
|
||||
|
||||
from project import Project
|
||||
|
||||
from .projectEntry_ui import Ui_ProjectEntry
|
||||
|
||||
|
||||
class ProjectEntry(Ui_ProjectEntry, QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setupUi(self)
|
||||
self.project = None
|
||||
|
||||
def setProject(self, project: Project):
|
||||
self.project = project
|
||||
self.updateLabels()
|
||||
|
||||
def updateLabels(self):
|
||||
if not self.project:
|
||||
self.projectNameLabel.setText("-")
|
||||
self.projectDescriptionLabel.setText("-")
|
||||
return
|
||||
|
||||
self.projectNameLabel.setText(self.project.name)
|
||||
self.projectDescriptionLabel.setText(
|
||||
"<br>".join(
|
||||
[
|
||||
str(self.project.path.resolve()),
|
||||
f"{len(self.project.sources)} sources",
|
||||
f"{len(self.project.samples)} samples ({len(self.project.samplesUnclassified)} unclassified)",
|
||||
]
|
||||
)
|
||||
)
|
116
ui/components/projectEntry.ui
Normal file
116
ui/components/projectEntry.ui
Normal file
@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ProjectEntry</class>
|
||||
<widget class="QWidget" name="ProjectEntry">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>605</width>
|
||||
<height>488</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>projectEntry</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tabManage">
|
||||
<attribute name="title">
|
||||
<string>Manage</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="text">
|
||||
<string>Extract</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="projectNameLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="pushButton_2">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="projectDescriptionLabel">
|
||||
<property name="text">
|
||||
<string>-</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<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>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabClassify">
|
||||
<attribute name="title">
|
||||
<string>Classify</string>
|
||||
</attribute>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="SamplesListWidget" name="unclassifiedListWidget"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QListWidget" name="tagsListWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="SamplesListWidget" name="classfiedListWidget"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>SamplesListWidget</class>
|
||||
<extends>QListWidget</extends>
|
||||
<header>ui.components.samplesListWidget</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
117
ui/components/projectEntry_ui.py
Normal file
117
ui/components/projectEntry_ui.py
Normal file
@ -0,0 +1,117 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'projectEntry.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, QGridLayout, QHBoxLayout, QLabel,
|
||||
QListWidget, QListWidgetItem, QPushButton, QSizePolicy,
|
||||
QSpacerItem, QTabWidget, QVBoxLayout, QWidget)
|
||||
|
||||
from ui.components.samplesListWidget import SamplesListWidget
|
||||
|
||||
class Ui_ProjectEntry(object):
|
||||
def setupUi(self, ProjectEntry):
|
||||
if not ProjectEntry.objectName():
|
||||
ProjectEntry.setObjectName(u"ProjectEntry")
|
||||
ProjectEntry.resize(605, 488)
|
||||
self.verticalLayout = QVBoxLayout(ProjectEntry)
|
||||
self.verticalLayout.setObjectName(u"verticalLayout")
|
||||
self.tabWidget = QTabWidget(ProjectEntry)
|
||||
self.tabWidget.setObjectName(u"tabWidget")
|
||||
self.tabManage = QWidget()
|
||||
self.tabManage.setObjectName(u"tabManage")
|
||||
self.gridLayout = QGridLayout(self.tabManage)
|
||||
self.gridLayout.setObjectName(u"gridLayout")
|
||||
self.pushButton = QPushButton(self.tabManage)
|
||||
self.pushButton.setObjectName(u"pushButton")
|
||||
|
||||
self.gridLayout.addWidget(self.pushButton, 2, 0, 1, 1)
|
||||
|
||||
self.projectNameLabel = QLabel(self.tabManage)
|
||||
self.projectNameLabel.setObjectName(u"projectNameLabel")
|
||||
font = QFont()
|
||||
font.setPointSize(14)
|
||||
font.setBold(True)
|
||||
self.projectNameLabel.setFont(font)
|
||||
|
||||
self.gridLayout.addWidget(self.projectNameLabel, 0, 0, 1, 2)
|
||||
|
||||
self.pushButton_2 = QPushButton(self.tabManage)
|
||||
self.pushButton_2.setObjectName(u"pushButton_2")
|
||||
|
||||
self.gridLayout.addWidget(self.pushButton_2, 2, 1, 1, 1)
|
||||
|
||||
self.projectDescriptionLabel = QLabel(self.tabManage)
|
||||
self.projectDescriptionLabel.setObjectName(u"projectDescriptionLabel")
|
||||
|
||||
self.gridLayout.addWidget(self.projectDescriptionLabel, 1, 0, 1, 2)
|
||||
|
||||
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||||
|
||||
self.gridLayout.addItem(self.verticalSpacer, 3, 0, 1, 2)
|
||||
|
||||
self.tabWidget.addTab(self.tabManage, "")
|
||||
self.tabClassify = QWidget()
|
||||
self.tabClassify.setObjectName(u"tabClassify")
|
||||
self.horizontalLayout = QHBoxLayout(self.tabClassify)
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.unclassifiedListWidget = SamplesListWidget(self.tabClassify)
|
||||
self.unclassifiedListWidget.setObjectName(u"unclassifiedListWidget")
|
||||
|
||||
self.horizontalLayout.addWidget(self.unclassifiedListWidget)
|
||||
|
||||
self.verticalLayout_2 = QVBoxLayout()
|
||||
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
||||
self.tagsListWidget = QListWidget(self.tabClassify)
|
||||
self.tagsListWidget.setObjectName(u"tagsListWidget")
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.tagsListWidget.sizePolicy().hasHeightForWidth())
|
||||
self.tagsListWidget.setSizePolicy(sizePolicy)
|
||||
|
||||
self.verticalLayout_2.addWidget(self.tagsListWidget)
|
||||
|
||||
self.classfiedListWidget = SamplesListWidget(self.tabClassify)
|
||||
self.classfiedListWidget.setObjectName(u"classfiedListWidget")
|
||||
|
||||
self.verticalLayout_2.addWidget(self.classfiedListWidget)
|
||||
|
||||
|
||||
self.horizontalLayout.addLayout(self.verticalLayout_2)
|
||||
|
||||
self.tabWidget.addTab(self.tabClassify, "")
|
||||
|
||||
self.verticalLayout.addWidget(self.tabWidget)
|
||||
|
||||
|
||||
self.retranslateUi(ProjectEntry)
|
||||
|
||||
self.tabWidget.setCurrentIndex(0)
|
||||
|
||||
|
||||
QMetaObject.connectSlotsByName(ProjectEntry)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, ProjectEntry):
|
||||
ProjectEntry.setWindowTitle(QCoreApplication.translate("ProjectEntry", u"projectEntry", None))
|
||||
self.pushButton.setText(QCoreApplication.translate("ProjectEntry", u"Extract", None))
|
||||
self.projectNameLabel.setText(QCoreApplication.translate("ProjectEntry", u"-", None))
|
||||
self.pushButton_2.setText(QCoreApplication.translate("ProjectEntry", u"...", None))
|
||||
self.projectDescriptionLabel.setText(QCoreApplication.translate("ProjectEntry", u"-", None))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tabManage), QCoreApplication.translate("ProjectEntry", u"Manage", None))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tabClassify), QCoreApplication.translate("ProjectEntry", u"Classify", None))
|
||||
# retranslateUi
|
||||
|
6
ui/components/samplesListWidget.py
Normal file
6
ui/components/samplesListWidget.py
Normal file
@ -0,0 +1,6 @@
|
||||
from PySide6.QtWidgets import QListWidget
|
||||
|
||||
|
||||
class SamplesListWidget(QListWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
43
ui/mainWindow.py
Normal file
43
ui/mainWindow.py
Normal file
@ -0,0 +1,43 @@
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtWidgets import QListWidgetItem, QMainWindow, QSizePolicy, QWidget
|
||||
|
||||
from .mainWindow_ui import Ui_MainWindow
|
||||
from .tabs.tabProjects import TabProjects
|
||||
|
||||
|
||||
class MainWindow(Ui_MainWindow, QMainWindow):
|
||||
TabWidgetTypeRole = Qt.ItemDataRole.UserRole + 10
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setupUi(self)
|
||||
|
||||
self.tabsListWidget.itemClicked.connect(self.setItemSelected)
|
||||
self.tabsListWidget.currentItemChanged.connect(self.switchTab)
|
||||
|
||||
projectsItem = QListWidgetItem("Projects", self.tabsListWidget)
|
||||
projectsItem.setData(self.TabWidgetTypeRole, TabProjects)
|
||||
self.tabsListWidget.addItem(projectsItem)
|
||||
|
||||
self.tabsListWidget.setMaximumWidth(
|
||||
self.tabsListWidget.sizeHintForColumn(0) + 10
|
||||
)
|
||||
|
||||
self.tabsListWidget.setCurrentIndex(self.tabsListWidget.model().index(0, 0))
|
||||
|
||||
def setItemSelected(self, item: QListWidgetItem):
|
||||
item.setSelected(True)
|
||||
|
||||
def switchTab(self):
|
||||
item = self.tabsListWidget.currentItem()
|
||||
|
||||
tabWidgetType = item.data(self.TabWidgetTypeRole)
|
||||
tabWidget: QWidget = tabWidgetType(self)
|
||||
# tabWidget.setSizePolicy(
|
||||
# QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred
|
||||
# )
|
||||
|
||||
self.centralWidget().layout().removeWidget(self.tabWidget)
|
||||
self.tabWidget.deleteLater()
|
||||
self.centralWidget().layout().addWidget(tabWidget)
|
||||
self.tabWidget = tabWidget
|
43
ui/mainWindow.ui
Normal file
43
ui/mainWindow.ui
Normal file
@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QListWidget" name="tabsListWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="tabWidget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
60
ui/mainWindow_ui.py
Normal file
60
ui/mainWindow_ui.py
Normal file
@ -0,0 +1,60 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'mainWindow.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, QHBoxLayout, QListWidget, QListWidgetItem,
|
||||
QMainWindow, QSizePolicy, QWidget)
|
||||
|
||||
class Ui_MainWindow(object):
|
||||
def setupUi(self, MainWindow):
|
||||
if not MainWindow.objectName():
|
||||
MainWindow.setObjectName(u"MainWindow")
|
||||
MainWindow.resize(800, 600)
|
||||
self.centralwidget = QWidget(MainWindow)
|
||||
self.centralwidget.setObjectName(u"centralwidget")
|
||||
self.horizontalLayout = QHBoxLayout(self.centralwidget)
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.tabsListWidget = QListWidget(self.centralwidget)
|
||||
self.tabsListWidget.setObjectName(u"tabsListWidget")
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.tabsListWidget.sizePolicy().hasHeightForWidth())
|
||||
self.tabsListWidget.setSizePolicy(sizePolicy)
|
||||
|
||||
self.horizontalLayout.addWidget(self.tabsListWidget)
|
||||
|
||||
self.tabWidget = QWidget(self.centralwidget)
|
||||
self.tabWidget.setObjectName(u"tabWidget")
|
||||
sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
|
||||
sizePolicy1.setHorizontalStretch(0)
|
||||
sizePolicy1.setVerticalStretch(0)
|
||||
sizePolicy1.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth())
|
||||
self.tabWidget.setSizePolicy(sizePolicy1)
|
||||
|
||||
self.horizontalLayout.addWidget(self.tabWidget)
|
||||
|
||||
MainWindow.setCentralWidget(self.centralwidget)
|
||||
|
||||
self.retranslateUi(MainWindow)
|
||||
|
||||
QMetaObject.connectSlotsByName(MainWindow)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, MainWindow):
|
||||
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
|
||||
# retranslateUi
|
||||
|
53
ui/tabs/tabProjects.py
Normal file
53
ui/tabs/tabProjects.py
Normal file
@ -0,0 +1,53 @@
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtWidgets import QListWidgetItem, QWidget
|
||||
|
||||
from project import Project, Projects
|
||||
|
||||
from ..components.projectEntry import ProjectEntry
|
||||
from .tabProjects_ui import Ui_TabProjects
|
||||
|
||||
|
||||
class ProjectListWidgetItem(QListWidgetItem):
|
||||
ProjectRole = Qt.ItemDataRole.UserRole
|
||||
|
||||
def __init__(self, project: Project, parent=None):
|
||||
super().__init__(parent, QListWidgetItem.ItemType.Type)
|
||||
self.setData(Qt.ItemDataRole.DisplayRole, project.name)
|
||||
self.setData(self.ProjectRole, project)
|
||||
|
||||
|
||||
class TabProjects(Ui_TabProjects, QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.setupUi(self)
|
||||
|
||||
self.projectListWidget.itemClicked.connect(
|
||||
self.projectListWidget.setCurrentItem
|
||||
)
|
||||
self.projectListWidget.currentItemChanged.connect(self.switchProject)
|
||||
|
||||
self.detectProjects()
|
||||
|
||||
def detectProjects(self):
|
||||
ps = Projects()
|
||||
ps.detectProjects()
|
||||
projects = ps.projects
|
||||
for project in projects:
|
||||
item = ProjectListWidgetItem(project, self.projectListWidget)
|
||||
self.projectListWidget.addItem(item)
|
||||
|
||||
self.projectListWidget.setMaximumWidth(
|
||||
self.projectListWidget.sizeHintForColumn(0) + 10
|
||||
)
|
||||
|
||||
def switchProject(self):
|
||||
item = self.projectListWidget.currentItem()
|
||||
project: Project = item.data(ProjectListWidgetItem.ProjectRole)
|
||||
|
||||
projectEntry = ProjectEntry(self)
|
||||
projectEntry.setProject(project)
|
||||
|
||||
self.layout().removeWidget(self.projectEntry)
|
||||
self.projectEntry.deleteLater()
|
||||
self.layout().addWidget(projectEntry)
|
||||
self.projectEntry = projectEntry
|
41
ui/tabs/tabProjects.ui
Normal file
41
ui/tabs/tabProjects.ui
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TabProjects</class>
|
||||
<widget class="QWidget" name="TabProjects">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>701</width>
|
||||
<height>582</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">TabProjects</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QListWidget" name="projectListWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="projectEntry" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
58
ui/tabs/tabProjects_ui.py
Normal file
58
ui/tabs/tabProjects_ui.py
Normal file
@ -0,0 +1,58 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
################################################################################
|
||||
## Form generated from reading UI file 'tabProjects.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, QHBoxLayout, QListWidget, QListWidgetItem,
|
||||
QSizePolicy, QWidget)
|
||||
|
||||
class Ui_TabProjects(object):
|
||||
def setupUi(self, TabProjects):
|
||||
if not TabProjects.objectName():
|
||||
TabProjects.setObjectName(u"TabProjects")
|
||||
TabProjects.resize(701, 582)
|
||||
TabProjects.setWindowTitle(u"TabProjects")
|
||||
self.horizontalLayout = QHBoxLayout(TabProjects)
|
||||
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
||||
self.projectListWidget = QListWidget(TabProjects)
|
||||
self.projectListWidget.setObjectName(u"projectListWidget")
|
||||
sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.projectListWidget.sizePolicy().hasHeightForWidth())
|
||||
self.projectListWidget.setSizePolicy(sizePolicy)
|
||||
|
||||
self.horizontalLayout.addWidget(self.projectListWidget)
|
||||
|
||||
self.projectEntry = QWidget(TabProjects)
|
||||
self.projectEntry.setObjectName(u"projectEntry")
|
||||
sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
|
||||
sizePolicy1.setHorizontalStretch(0)
|
||||
sizePolicy1.setVerticalStretch(0)
|
||||
sizePolicy1.setHeightForWidth(self.projectEntry.sizePolicy().hasHeightForWidth())
|
||||
self.projectEntry.setSizePolicy(sizePolicy1)
|
||||
|
||||
self.horizontalLayout.addWidget(self.projectEntry)
|
||||
|
||||
|
||||
self.retranslateUi(TabProjects)
|
||||
|
||||
QMetaObject.connectSlotsByName(TabProjects)
|
||||
# setupUi
|
||||
|
||||
def retranslateUi(self, TabProjects):
|
||||
pass
|
||||
# retranslateUi
|
||||
|
11
uiIndex.py
Normal file
11
uiIndex.py
Normal file
@ -0,0 +1,11 @@
|
||||
import sys
|
||||
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
from ui.mainWindow import MainWindow
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv)
|
||||
window = MainWindow()
|
||||
window.show()
|
||||
sys.exit(app.exec())
|
Loading…
x
Reference in New Issue
Block a user