Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleClas
提交
f64bec7f
P
PaddleClas
项目概览
PaddlePaddle
/
PaddleClas
1 年多 前同步成功
通知
116
Star
4999
Fork
1114
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
19
列表
看板
标记
里程碑
合并请求
6
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleClas
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
19
Issue
19
列表
看板
标记
里程碑
合并请求
6
合并请求
6
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
f64bec7f
编写于
9月 03, 2022
作者:
D
dongshuilong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add shitu_index_manager
上级
898f12c3
变更
30
展开全部
隐藏空白更改
内联
并排
Showing
30 changed file
with
2874 addition
and
0 deletion
+2874
-0
deploy/shitu_index_manager/README.md
deploy/shitu_index_manager/README.md
+1
-0
deploy/shitu_index_manager/index_manager.py
deploy/shitu_index_manager/index_manager.py
+349
-0
deploy/shitu_index_manager/mod/__init__.py
deploy/shitu_index_manager/mod/__init__.py
+0
-0
deploy/shitu_index_manager/mod/classify_ui_context.py
deploy/shitu_index_manager/mod/classify_ui_context.py
+144
-0
deploy/shitu_index_manager/mod/image_list_manager.py
deploy/shitu_index_manager/mod/image_list_manager.py
+236
-0
deploy/shitu_index_manager/mod/image_list_ui_context.py
deploy/shitu_index_manager/mod/image_list_ui_context.py
+231
-0
deploy/shitu_index_manager/mod/imageeditclassifydialog.py
deploy/shitu_index_manager/mod/imageeditclassifydialog.py
+52
-0
deploy/shitu_index_manager/mod/index_http_client.py
deploy/shitu_index_manager/mod/index_http_client.py
+60
-0
deploy/shitu_index_manager/mod/mainwindow.py
deploy/shitu_index_manager/mod/mainwindow.py
+492
-0
deploy/shitu_index_manager/mod/ui_addclassifydialog.py
deploy/shitu_index_manager/mod/ui_addclassifydialog.py
+56
-0
deploy/shitu_index_manager/mod/ui_imageeditclassifydialog.py
deploy/shitu_index_manager/mod/ui_imageeditclassifydialog.py
+75
-0
deploy/shitu_index_manager/mod/ui_mainwindow.py
deploy/shitu_index_manager/mod/ui_mainwindow.py
+155
-0
deploy/shitu_index_manager/mod/ui_newlibrarydialog.py
deploy/shitu_index_manager/mod/ui_newlibrarydialog.py
+71
-0
deploy/shitu_index_manager/mod/ui_renameclassifydialog.py
deploy/shitu_index_manager/mod/ui_renameclassifydialog.py
+63
-0
deploy/shitu_index_manager/mod/ui_waitdialog.py
deploy/shitu_index_manager/mod/ui_waitdialog.py
+49
-0
deploy/shitu_index_manager/mod/utils.py
deploy/shitu_index_manager/mod/utils.py
+142
-0
deploy/shitu_index_manager/resource/add_classify.png
deploy/shitu_index_manager/resource/add_classify.png
+0
-0
deploy/shitu_index_manager/resource/add_image.png
deploy/shitu_index_manager/resource/add_image.png
+0
-0
deploy/shitu_index_manager/resource/app_icon.png
deploy/shitu_index_manager/resource/app_icon.png
+0
-0
deploy/shitu_index_manager/resource/app_menu.png
deploy/shitu_index_manager/resource/app_menu.png
+0
-0
deploy/shitu_index_manager/resource/remove_classify.png
deploy/shitu_index_manager/resource/remove_classify.png
+0
-0
deploy/shitu_index_manager/resource/remove_image.png
deploy/shitu_index_manager/resource/remove_image.png
+0
-0
deploy/shitu_index_manager/resource/save_image_Library.png
deploy/shitu_index_manager/resource/save_image_Library.png
+0
-0
deploy/shitu_index_manager/resource/search_classify.png
deploy/shitu_index_manager/resource/search_classify.png
+0
-0
deploy/shitu_index_manager/ui/AddClassifyDialog.ui
deploy/shitu_index_manager/ui/AddClassifyDialog.ui
+90
-0
deploy/shitu_index_manager/ui/ImageEditClassifyDialog.ui
deploy/shitu_index_manager/ui/ImageEditClassifyDialog.ui
+125
-0
deploy/shitu_index_manager/ui/MainWindow.ui
deploy/shitu_index_manager/ui/MainWindow.ui
+212
-0
deploy/shitu_index_manager/ui/NewlibraryDialog.ui
deploy/shitu_index_manager/ui/NewlibraryDialog.ui
+116
-0
deploy/shitu_index_manager/ui/RenameClassifyDialog.ui
deploy/shitu_index_manager/ui/RenameClassifyDialog.ui
+101
-0
deploy/shitu_index_manager/ui/WaitDialog.ui
deploy/shitu_index_manager/ui/WaitDialog.ui
+54
-0
未找到文件。
deploy/shitu_index_manager/README.md
0 → 120000
浏览文件 @
f64bec7f
../../docs/zh_CN/inference_deployment/shitu_gallery_manager.md
\ No newline at end of file
deploy/shitu_index_manager/index_manager.py
0 → 100644
浏览文件 @
f64bec7f
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import
os
import
sys
from
PyQt5
import
QtCore
,
QtGui
,
QtWidgets
import
mod.mainwindow
from
paddleclas.deploy.utils
import
config
,
logger
from
paddleclas.deploy.python.predict_rec
import
RecPredictor
from
fastapi
import
FastAPI
import
uvicorn
import
numpy
as
np
import
faiss
from
typing
import
List
import
pickle
import
cv2
import
socket
import
json
import
operator
from
multiprocessing
import
Process
"""
完整的index库如下:
root_path/ # 库存储目录
|-- image_list.txt # 图像列表,每行:image_path label。由前端生成及修改。后端只读
|-- features.pkl # 建库之后,保存的embedding向量,后端生成,前端无需操作
|-- images # 图像存储目录,由前端生成及增删查等操作。后端只读
| |-- md5.jpg
| |-- md5.jpg
| |-- ……
|-- index # 真正的生成的index库存储目录,后端生成及操作,前端无需操作。
| |-- vector.index # faiss生成的索引库
| |-- id_map.pkl # 索引文件
"""
class
ShiTuIndexManager
(
object
):
def
__init__
(
self
,
config
):
self
.
root_path
=
None
self
.
image_list_path
=
"image_list.txt"
self
.
image_dir
=
"images"
self
.
index_path
=
"index/vector.index"
self
.
id_map_path
=
"index/id_map.pkl"
self
.
features_path
=
"features.pkl"
self
.
index
=
None
self
.
id_map
=
None
self
.
features
=
None
self
.
config
=
config
self
.
predictor
=
RecPredictor
(
config
)
def
_load_pickle
(
self
,
path
):
if
os
.
path
.
exists
(
path
):
return
pickle
.
load
(
open
(
path
,
'rb'
))
else
:
return
None
def
_save_pickle
(
self
,
path
,
data
):
if
not
os
.
path
.
exists
(
os
.
path
.
dirname
(
path
)):
os
.
makedirs
(
os
.
path
.
dirname
(
path
),
exist_ok
=
True
)
with
open
(
path
,
'wb'
)
as
fd
:
pickle
.
dump
(
data
,
fd
)
def
_load_index
(
self
):
self
.
index
=
faiss
.
read_index
(
os
.
path
.
join
(
self
.
root_path
,
self
.
index_path
))
self
.
id_map
=
self
.
_load_pickle
(
os
.
path
.
join
(
self
.
root_path
,
self
.
id_map_path
))
self
.
features
=
self
.
_load_pickle
(
os
.
path
.
join
(
self
.
root_path
,
self
.
features_path
))
def
_save_index
(
self
,
index
,
id_map
,
features
):
faiss
.
write_index
(
index
,
os
.
path
.
join
(
self
.
root_path
,
self
.
index_path
))
self
.
_save_pickle
(
os
.
path
.
join
(
self
.
root_path
,
self
.
id_map_path
),
id_map
)
self
.
_save_pickle
(
os
.
path
.
join
(
self
.
root_path
,
self
.
features_path
),
features
)
def
_update_path
(
self
,
root_path
,
image_list_path
=
None
):
if
root_path
==
self
.
root_path
:
pass
else
:
self
.
root_path
=
root_path
if
not
os
.
path
.
exists
(
os
.
path
.
join
(
root_path
,
"index"
)):
os
.
mkdir
(
os
.
path
.
join
(
root_path
,
"index"
))
if
image_list_path
is
not
None
:
self
.
image_list_path
=
image_list_path
def
_cal_featrue
(
self
,
image_list
):
batch_images
=
[]
featrures
=
None
cnt
=
0
for
idx
,
image_path
in
enumerate
(
image_list
):
image
=
cv2
.
imread
(
image_path
)
if
image
is
None
:
return
"{} is broken or not exist. Stop"
else
:
image
=
image
[:,
:,
::
-
1
]
batch_images
.
append
(
image
)
cnt
+=
1
if
cnt
%
self
.
config
[
"Global"
][
"batch_size"
]
==
0
or
(
idx
+
1
)
==
len
(
image_list
):
if
len
(
batch_images
)
==
0
:
continue
batch_results
=
self
.
predictor
.
predict
(
batch_images
)
featrures
=
batch_results
if
featrures
is
None
else
np
.
concatenate
(
(
featrures
,
batch_results
),
axis
=
0
)
batch_images
=
[]
return
featrures
def
_split_datafile
(
self
,
data_file
,
image_root
):
'''
data_file: image path and info, which can be splitted by spacer
image_root: image path root
delimiter: delimiter
'''
gallery_images
=
[]
gallery_docs
=
[]
gallery_ids
=
[]
with
open
(
data_file
,
'r'
,
encoding
=
'utf-8'
)
as
f
:
lines
=
f
.
readlines
()
for
_
,
ori_line
in
enumerate
(
lines
):
line
=
ori_line
.
strip
().
split
()
text_num
=
len
(
line
)
assert
text_num
>=
2
,
f
"line(
{
ori_line
}
) must be splitted into at least 2 parts, but got
{
text_num
}
"
image_file
=
os
.
path
.
join
(
image_root
,
line
[
0
])
gallery_images
.
append
(
image_file
)
gallery_docs
.
append
(
ori_line
.
strip
())
gallery_ids
.
append
(
os
.
path
.
basename
(
line
[
0
]).
split
(
"."
)[
0
])
return
gallery_images
,
gallery_docs
,
gallery_ids
def
create_index
(
self
,
image_list
:
str
,
index_method
:
str
=
"HNSW32"
,
image_root
:
str
=
None
):
if
not
os
.
path
.
exists
(
image_list
):
return
"{} is not exist"
.
format
(
image_list
)
if
index_method
.
lower
()
not
in
[
'hnsw32'
,
'ivf'
,
'flat'
]:
return
"The index method Only support: HNSW32, IVF, Flat"
self
.
_update_path
(
os
.
path
.
dirname
(
image_list
),
image_list
)
# get image_paths
image_root
=
image_root
if
image_root
is
not
None
else
self
.
root_path
gallery_images
,
gallery_docs
,
image_ids
=
self
.
_split_datafile
(
image_list
,
image_root
)
# gernerate index
if
index_method
==
"IVF"
:
index_method
=
index_method
+
str
(
min
(
max
(
int
(
len
(
gallery_images
)
//
32
),
2
),
65536
))
+
",Flat"
index
=
faiss
.
index_factory
(
self
.
config
[
"IndexProcess"
][
"embedding_size"
],
index_method
,
faiss
.
METRIC_INNER_PRODUCT
)
self
.
index
=
faiss
.
IndexIDMap2
(
index
)
features
=
self
.
_cal_featrue
(
gallery_images
)
self
.
index
.
train
(
features
)
index_ids
=
np
.
arange
(
0
,
len
(
gallery_images
)).
astype
(
np
.
int64
)
self
.
index
.
add_with_ids
(
features
,
index_ids
)
self
.
id_map
=
dict
()
for
i
,
d
in
zip
(
list
(
index_ids
),
gallery_docs
):
self
.
id_map
[
i
]
=
d
self
.
features
=
{
"features"
:
features
,
"index_method"
:
index_method
,
"image_ids"
:
image_ids
,
"index_ids"
:
index_ids
.
tolist
()
}
self
.
_save_index
(
self
.
index
,
self
.
id_map
,
self
.
features
)
def
open_index
(
self
,
root_path
:
str
,
image_list_path
:
str
)
->
str
:
self
.
_update_path
(
root_path
)
_
,
_
,
image_ids
=
self
.
_split_datafile
(
image_list_path
,
root_path
)
if
os
.
path
.
exists
(
os
.
path
.
join
(
self
.
root_path
,
self
.
index_path
))
and
\
os
.
path
.
exists
(
os
.
path
.
join
(
self
.
root_path
,
self
.
id_map_path
))
and
\
os
.
path
.
exists
(
os
.
path
.
join
(
self
.
root_path
,
self
.
features_path
)):
self
.
_update_path
(
root_path
)
self
.
_load_index
()
if
operator
.
eq
(
set
(
image_ids
),
set
(
self
.
features
[
'image_ids'
])):
return
""
else
:
return
"The image list is different from index, Please update index"
else
:
return
"File not exist: features.pkl, vector.index, id_map.pkl"
def
update_index
(
self
,
image_list
:
str
,
image_root
:
str
=
None
)
->
str
:
if
self
.
index
and
self
.
id_map
and
self
.
features
:
image_paths
,
image_docs
,
image_ids
=
self
.
_split_datafile
(
image_list
,
image_root
if
image_root
is
not
None
else
self
.
root_path
)
# for add image
add_ids
=
list
(
set
(
image_ids
).
difference
(
set
(
self
.
features
[
"image_ids"
])))
add_indexes
=
[
i
for
i
,
x
in
enumerate
(
image_ids
)
if
x
in
add_ids
]
add_image_paths
=
[
image_paths
[
i
]
for
i
in
add_indexes
]
add_image_docs
=
[
image_docs
[
i
]
for
i
in
add_indexes
]
add_image_ids
=
[
image_ids
[
i
]
for
i
in
add_indexes
]
self
.
_add_index
(
add_image_paths
,
add_image_docs
,
add_image_ids
)
# delete images
delete_ids
=
list
(
set
(
self
.
features
[
"image_ids"
]).
difference
(
set
(
image_ids
)))
self
.
_delete_index
(
delete_ids
)
self
.
_save_index
(
self
.
index
,
self
.
id_map
,
self
.
features
)
return
""
else
:
return
"Failed. Please create or open index first"
def
_add_index
(
self
,
image_list
:
List
,
image_docs
:
List
,
image_ids
:
List
):
if
len
(
image_ids
)
==
0
:
return
featrures
=
self
.
_cal_featrue
(
image_list
)
index_ids
=
(
np
.
arange
(
0
,
len
(
image_list
))
+
max
(
self
.
id_map
.
keys
())
+
1
).
astype
(
np
.
int64
)
self
.
index
.
add_with_ids
(
featrures
,
index_ids
)
for
i
,
d
in
zip
(
index_ids
,
image_docs
):
self
.
id_map
[
i
]
=
d
self
.
features
[
'features'
]
=
np
.
concatenate
(
[
self
.
features
[
'features'
],
featrures
],
axis
=
0
)
self
.
features
[
'image_ids'
].
extend
(
image_ids
)
self
.
features
[
'index_ids'
].
extend
(
index_ids
.
tolist
())
def
_delete_index
(
self
,
image_ids
:
List
):
if
len
(
image_ids
)
==
0
:
return
indexes
=
[
i
for
i
,
x
in
enumerate
(
self
.
features
[
'image_ids'
])
if
x
in
image_ids
]
self
.
features
[
"features"
]
=
np
.
delete
(
self
.
features
[
"features"
],
indexes
,
axis
=
0
)
self
.
features
[
"image_ids"
]
=
np
.
delete
(
np
.
asarray
(
self
.
features
[
"image_ids"
]),
indexes
,
axis
=
0
).
tolist
()
index_ids
=
np
.
delete
(
np
.
asarray
(
self
.
features
[
"index_ids"
]),
indexes
,
axis
=
0
).
tolist
()
id_map_values
=
[
self
.
id_map
[
i
]
for
i
in
index_ids
]
self
.
index
.
reset
()
ids
=
np
.
arange
(
0
,
len
(
id_map_values
)).
astype
(
np
.
int64
)
self
.
index
.
add_with_ids
(
self
.
features
[
'features'
],
ids
)
self
.
id_map
.
clear
()
for
i
,
d
in
zip
(
ids
,
id_map_values
):
self
.
id_map
[
i
]
=
d
self
.
features
[
"index_ids"
]
=
ids
app
=
FastAPI
()
@
app
.
get
(
"/new_index"
)
def
new_index
(
image_list_path
:
str
,
index_method
:
str
=
"HNSW32"
,
index_root_path
:
str
=
None
,
force
:
bool
=
False
):
result
=
""
try
:
if
index_root_path
is
not
None
:
image_list_path
=
os
.
path
.
join
(
index_root_path
,
image_list_path
)
index_path
=
os
.
path
.
join
(
index_root_path
,
"index"
,
"vector.index"
)
id_map_path
=
os
.
path
.
join
(
index_root_path
,
"index"
,
"id_map.pkl"
)
if
not
(
os
.
path
.
exists
(
index_path
)
and
os
.
path
.
exists
(
id_map_path
))
or
force
:
manager
.
create_index
(
image_list_path
,
index_method
,
index_root_path
)
else
:
result
=
"There alrealy has index in {}"
.
format
(
index_root_path
)
except
Exception
as
e
:
result
=
e
.
__str__
()
data
=
{
"error_message"
:
result
}
return
json
.
dumps
(
data
).
encode
()
@
app
.
get
(
"/open_index"
)
def
open_index
(
index_root_path
:
str
,
image_list_path
:
str
):
result
=
""
try
:
image_list_path
=
os
.
path
.
join
(
index_root_path
,
image_list_path
)
result
=
manager
.
open_index
(
index_root_path
,
image_list_path
)
except
Exception
as
e
:
result
=
e
.
__str__
()
data
=
{
"error_message"
:
result
}
return
json
.
dumps
(
data
).
encode
()
@
app
.
get
(
"/update_index"
)
def
update_index
(
image_list_path
:
str
,
index_root_path
:
str
=
None
):
result
=
""
try
:
if
index_root_path
is
not
None
:
image_list_path
=
os
.
path
.
join
(
index_root_path
,
image_list_path
)
result
=
manager
.
update_index
(
image_list
=
image_list_path
,
image_root
=
index_root_path
)
except
Exception
as
e
:
result
=
e
.
__str__
()
data
=
{
"error_message"
:
result
}
return
json
.
dumps
(
data
).
encode
()
def
FrontInterface
(
server_process
=
None
):
front
=
QtWidgets
.
QApplication
([])
main_window
=
mod
.
mainwindow
.
MainWindow
(
process
=
server_process
)
main_window
.
showMaximized
()
sys
.
exit
(
front
.
exec_
())
def
Server
(
args
):
[
app
,
host
,
port
]
=
args
uvicorn
.
run
(
app
,
host
=
host
,
port
=
port
)
if
__name__
==
'__main__'
:
args
=
config
.
parse_args
()
model_config
=
config
.
get_config
(
args
.
config
,
overrides
=
args
.
override
,
show
=
True
)
manager
=
ShiTuIndexManager
(
model_config
)
try
:
ip
=
socket
.
gethostbyname
(
socket
.
gethostname
())
except
:
ip
=
'127.0.0.1'
port
=
8000
p_server
=
Process
(
target
=
Server
,
args
=
([
app
,
ip
,
port
],))
p_server
.
start
()
# p_client = Process(target=FrontInterface, args=())
# p_client.start()
# p_client.join()
FrontInterface
(
p_server
)
p_server
.
terminate
()
sys
.
exit
(
0
)
deploy/shitu_index_manager/mod/__init__.py
0 → 100644
浏览文件 @
f64bec7f
deploy/shitu_index_manager/mod/classify_ui_context.py
0 → 100644
浏览文件 @
f64bec7f
import
os
from
PyQt5
import
QtCore
,
QtWidgets
from
mod
import
image_list_manager
as
imglistmgr
from
mod
import
utils
from
mod
import
ui_addclassifydialog
from
mod
import
ui_renameclassifydialog
class
ClassifyUiContext
(
QtCore
.
QObject
):
# 分类界面相关业务
selected
=
QtCore
.
pyqtSignal
(
str
)
# 选择分类信号
def
__init__
(
self
,
ui
:
QtWidgets
.
QListView
,
parent
:
QtWidgets
.
QMainWindow
,
image_list_mgr
:
imglistmgr
.
ImageListManager
):
super
(
ClassifyUiContext
,
self
).
__init__
()
self
.
__ui
=
ui
self
.
__parent
=
parent
self
.
__imageListMgr
=
image_list_mgr
self
.
__menu
=
QtWidgets
.
QMenu
()
self
.
__initMenu
()
self
.
__initUi
()
self
.
__connectSignal
()
@
property
def
ui
(
self
):
return
self
.
__ui
@
property
def
parent
(
self
):
return
self
.
__parent
@
property
def
imageListManager
(
self
):
return
self
.
__imageListMgr
@
property
def
menu
(
self
):
return
self
.
__menu
def
__initUi
(
self
):
"""初始化分类界面"""
self
.
__ui
.
setEditTriggers
(
QtWidgets
.
QAbstractItemView
.
NoEditTriggers
)
def
__connectSignal
(
self
):
"""连接信号"""
self
.
__ui
.
clicked
.
connect
(
self
.
uiClicked
)
self
.
__ui
.
doubleClicked
.
connect
(
self
.
uiDoubleClicked
)
def
__initMenu
(
self
):
"""初始化分类界面菜单"""
utils
.
setMenu
(
self
.
__menu
,
"添加分类"
,
self
.
addClassify
)
utils
.
setMenu
(
self
.
__menu
,
"移除分类"
,
self
.
removeClassify
)
utils
.
setMenu
(
self
.
__menu
,
"重命名分类"
,
self
.
renemeClassify
)
self
.
__ui
.
setContextMenuPolicy
(
QtCore
.
Qt
.
CustomContextMenu
)
self
.
__ui
.
customContextMenuRequested
.
connect
(
self
.
__showMenu
)
def
__showMenu
(
self
,
pos
):
"""显示分类界面菜单"""
if
len
(
self
.
__imageListMgr
.
filePath
)
>
0
:
self
.
__menu
.
exec_
(
self
.
__ui
.
mapToGlobal
(
pos
))
def
setClassifyList
(
self
,
classify_list
):
"""设置分类列表"""
list_model
=
QtCore
.
QStringListModel
(
classify_list
)
self
.
__ui
.
setModel
(
list_model
)
def
uiClicked
(
self
,
index
):
"""分类列表点击"""
if
not
self
.
__ui
.
currentIndex
().
isValid
():
return
txt
=
index
.
data
()
self
.
selected
.
emit
(
txt
)
def
uiDoubleClicked
(
self
,
index
):
"""分类列表双击"""
if
not
self
.
__ui
.
currentIndex
().
isValid
():
return
ole_name
=
index
.
data
()
dlg
=
QtWidgets
.
QDialog
(
parent
=
self
.
parent
)
ui
=
ui_renameclassifydialog
.
Ui_RenameClassifyDialog
()
ui
.
setupUi
(
dlg
)
ui
.
oldNameLineEdit
.
setText
(
ole_name
)
result
=
dlg
.
exec_
()
new_name
=
ui
.
newNameLineEdit
.
text
()
if
result
==
QtWidgets
.
QDialog
.
Accepted
:
mgr_result
=
self
.
__imageListMgr
.
renameClassify
(
ole_name
,
new_name
)
if
not
mgr_result
:
QtWidgets
.
QMessageBox
.
warning
(
self
.
parent
,
"重命名分类"
,
"重命名分类错误"
)
else
:
self
.
setClassifyList
(
self
.
__imageListMgr
.
classifyList
)
self
.
__imageListMgr
.
writeFile
()
def
addClassify
(
self
):
"""添加分类"""
if
not
os
.
path
.
exists
(
self
.
__imageListMgr
.
filePath
):
QtWidgets
.
QMessageBox
.
information
(
self
.
__parent
,
"提示"
,
"请先打开正确的图像库"
)
return
dlg
=
QtWidgets
.
QDialog
(
parent
=
self
.
parent
)
ui
=
ui_addclassifydialog
.
Ui_AddClassifyDialog
()
ui
.
setupUi
(
dlg
)
result
=
dlg
.
exec_
()
txt
=
ui
.
lineEdit
.
text
()
if
result
==
QtWidgets
.
QDialog
.
Accepted
:
mgr_result
=
self
.
__imageListMgr
.
addClassify
(
txt
)
if
not
mgr_result
:
QtWidgets
.
QMessageBox
.
warning
(
self
.
parent
,
"添加分类"
,
"添加分类错误"
)
else
:
self
.
setClassifyList
(
self
.
__imageListMgr
.
classifyList
)
def
removeClassify
(
self
):
"""移除分类"""
if
not
os
.
path
.
exists
(
self
.
__imageListMgr
.
filePath
):
QtWidgets
.
QMessageBox
.
information
(
self
.
__parent
,
"提示"
,
"请先打开正确的图像库"
)
return
if
not
self
.
__ui
.
currentIndex
().
isValid
():
return
classify
=
self
.
__ui
.
currentIndex
().
data
()
result
=
QtWidgets
.
QMessageBox
.
information
(
self
.
parent
,
"移除分类"
,
"确定移除分类: {}"
.
format
(
classify
),
buttons
=
QtWidgets
.
QMessageBox
.
Ok
|
QtWidgets
.
QMessageBox
.
Cancel
,
defaultButton
=
QtWidgets
.
QMessageBox
.
Cancel
)
if
result
==
QtWidgets
.
QMessageBox
.
Ok
:
if
len
(
self
.
__imageListMgr
.
imageList
(
classify
))
>
0
:
QtWidgets
.
QMessageBox
.
warning
(
self
.
parent
,
"移除分类"
,
"分类下存在图片,请先移除图片"
)
else
:
self
.
__imageListMgr
.
removeClassify
(
classify
)
self
.
setClassifyList
(
self
.
__imageListMgr
.
classifyList
())
def
renemeClassify
(
self
):
"""重命名分类"""
idx
=
self
.
__ui
.
currentIndex
()
if
idx
.
isValid
():
self
.
uiDoubleClicked
(
idx
)
def
searchClassify
(
self
,
classify
):
"""查找分类"""
self
.
setClassifyList
(
self
.
__imageListMgr
.
findLikeClassify
(
classify
))
deploy/shitu_index_manager/mod/image_list_manager.py
0 → 100644
浏览文件 @
f64bec7f
import
os
class
ImageListManager
:
"""
图像列表文件管理器
"""
def
__init__
(
self
,
file_path
=
""
,
encoding
=
"utf-8"
):
self
.
__filePath
=
""
self
.
__dirName
=
""
self
.
__dataList
=
{}
self
.
__findLikeClassifyResult
=
[]
if
file_path
!=
""
:
self
.
readFile
(
file_path
,
encoding
)
@
property
def
filePath
(
self
):
return
self
.
__filePath
@
property
def
dirName
(
self
):
return
self
.
__dirName
@
dirName
.
setter
def
dirName
(
self
,
value
):
self
.
__dirName
=
value
@
property
def
dataList
(
self
):
return
self
.
__dataList
@
property
def
classifyList
(
self
):
return
self
.
__dataList
.
keys
()
@
property
def
findLikeClassifyResult
(
self
):
return
self
.
__findLikeClassifyResult
def
imageList
(
self
,
classify
:
str
):
"""
获取分类下的图片列表
Args:
classify (str): 分类名称
Returns:
list: 图片列表
"""
return
self
.
__dataList
[
classify
]
def
readFile
(
self
,
file_path
:
str
,
encoding
=
"utf-8"
):
"""
读取文件内容
Args:
file_path (str): 文件路径
encoding (str, optional): 文件编码. 默认 "utf-8".
Raises:
Exception: 文件不存在
"""
if
not
os
.
path
.
exists
(
file_path
):
raise
Exception
(
"文件不存在:{}"
.
format
(
file_path
))
self
.
__filePath
=
file_path
self
.
__dirName
=
os
.
path
.
dirname
(
self
.
__filePath
)
self
.
__readData
(
file_path
,
encoding
)
def
__readData
(
self
,
file_path
:
str
,
encoding
=
"utf-8"
):
"""
读取文件内容
Args:
file_path (str): 文件路径
encoding (str, optional): 文件编码. 默认 "utf-8".
"""
with
open
(
file_path
,
"r"
,
encoding
=
encoding
)
as
f
:
self
.
__dataList
.
clear
()
for
line
in
f
:
line
=
line
.
rstrip
(
"
\n
"
)
data
=
line
.
split
(
"
\t
"
)
self
.
__appendData
(
data
)
def
__appendData
(
self
,
data
:
list
):
"""
添加数据
Args:
data (list): 数据
"""
if
data
[
1
]
not
in
self
.
__dataList
:
self
.
__dataList
[
data
[
1
]]
=
[]
self
.
__dataList
[
data
[
1
]].
append
(
data
[
0
])
def
writeFile
(
self
,
file_path
=
""
,
encoding
=
"utf-8"
):
"""
写入文件
Args:
file_path (str, optional): 文件路径. 默认 "".
encoding (str, optional): 文件编码. 默认 "utf-8".
"""
if
file_path
==
""
:
file_path
=
self
.
__filePath
if
not
os
.
path
.
exists
(
file_path
):
return
False
self
.
__dirName
=
os
.
path
.
dirname
(
self
.
__filePath
)
lines
=
[]
for
classify
in
self
.
__dataList
.
keys
():
for
path
in
self
.
__dataList
[
classify
]:
lines
.
append
(
"{}
\t
{}
\n
"
.
format
(
path
,
classify
))
with
open
(
file_path
,
"w"
,
encoding
=
encoding
)
as
f
:
f
.
writelines
(
lines
)
return
True
def
realPath
(
self
,
image_path
:
str
):
"""
获取真实路径
Args:
image_path (str): 图片路径
"""
return
os
.
path
.
join
(
self
.
__dirName
,
image_path
)
def
realPathList
(
self
,
classify
:
str
):
"""
获取分类下的真实路径列表
Args:
classify (str): 分类名称
Returns:
list: 真实路径列表
"""
if
classify
not
in
self
.
classifyList
:
return
[]
paths
=
self
.
__dataList
[
classify
]
if
len
(
paths
)
==
0
:
return
[]
for
i
in
range
(
len
(
paths
)):
paths
[
i
]
=
os
.
path
.
join
(
self
.
__dirName
,
paths
[
i
])
return
paths
def
findLikeClassify
(
self
,
name
:
str
):
"""
查找类似的分类名称
Args:
name (str): 分类名称
Returns:
list: 类似的分类名称列表
"""
self
.
__findLikeClassifyResult
.
clear
()
for
classify
in
self
.
__dataList
.
keys
():
word
=
str
(
name
)
if
(
word
in
classify
):
self
.
__findLikeClassifyResult
.
append
(
classify
)
return
self
.
__findLikeClassifyResult
def
addClassify
(
self
,
classify
:
str
):
"""
添加分类
Args:
classify (str): 分类名称
Returns:
bool: 如果分类名称已经存在,返回False,否则添加分类并返回True
"""
if
classify
in
self
.
__dataList
:
return
False
self
.
__dataList
[
classify
]
=
[]
return
True
def
removeClassify
(
self
,
classify
:
str
):
"""
移除分类
Args:
classify (str): 分类名称
Returns:
bool: 如果分类名称不存在,返回False,否则移除分类并返回True
"""
if
classify
not
in
self
.
__dataList
:
return
False
self
.
__dataList
.
pop
(
classify
)
return
True
def
renameClassify
(
self
,
old_classify
:
str
,
new_classify
:
str
):
"""
重命名分类名称
Args:
old_classify (str): 原分类名称
new_classify (str): 新分类名称
Returns:
bool: 如果原分类名称不存在,或者新分类名称已经存在,返回False,否则重命名分类名称并返回True
"""
if
old_classify
not
in
self
.
__dataList
:
return
False
if
new_classify
in
self
.
__dataList
:
return
False
self
.
__dataList
[
new_classify
]
=
self
.
__dataList
[
old_classify
]
self
.
__dataList
.
pop
(
old_classify
)
return
True
def
allClassfiyNotEmpty
(
self
):
"""
检查所有分类是否都有图片
Returns:
bool: 如果有一个分类没有图片,返回False,否则返回True
"""
for
classify
in
self
.
__dataList
.
keys
():
if
len
(
self
.
__dataList
[
classify
])
==
0
:
return
False
return
True
def
resetImageList
(
self
,
classify
:
str
,
image_list
:
list
):
"""
重置图片列表
Args:
classify (str): 分类名称
image_list (list): 图片相对路径列表
Returns:
bool: 如果分类名称不存在,返回False,否则重置图片列表并返回True
"""
if
classify
not
in
self
.
__dataList
:
return
False
self
.
__dataList
[
classify
]
=
image_list
return
True
deploy/shitu_index_manager/mod/image_list_ui_context.py
0 → 100644
浏览文件 @
f64bec7f
import
os
from
stat
import
filemode
from
PyQt5
import
QtCore
,
QtGui
,
QtWidgets
from
mod
import
image_list_manager
as
imglistmgr
from
mod
import
utils
from
mod
import
ui_renameclassifydialog
from
mod
import
imageeditclassifydialog
# 图像缩放基数
BASE_IMAGE_SIZE
=
64
class
ImageListUiContext
(
QtCore
.
QObject
):
# 图片列表界面相关业务,style sheet 在 MainWindow.ui 相应的 ImageListWidget 中设置
listCount
=
QtCore
.
pyqtSignal
(
int
)
# 图像列表图像的数量
selectedCount
=
QtCore
.
pyqtSignal
(
int
)
# 图像列表选择图像的数量
def
__init__
(
self
,
ui
:
QtWidgets
.
QListWidget
,
parent
:
QtWidgets
.
QMainWindow
,
image_list_mgr
:
imglistmgr
.
ImageListManager
):
super
(
ImageListUiContext
,
self
).
__init__
()
self
.
__ui
=
ui
self
.
__parent
=
parent
self
.
__imageListMgr
=
image_list_mgr
self
.
__initUi
()
self
.
__menu
=
QtWidgets
.
QMenu
()
self
.
__initMenu
()
self
.
__connectSignal
()
self
.
__selectedClassify
=
""
self
.
__imageScale
=
1
@
property
def
ui
(
self
):
return
self
.
__ui
@
property
def
parent
(
self
):
return
self
.
__parent
@
property
def
imageListManager
(
self
):
return
self
.
__imageListMgr
@
property
def
menu
(
self
):
return
self
.
__menu
def
__initUi
(
self
):
"""初始化图片列表样式"""
self
.
__ui
.
setViewMode
(
QtWidgets
.
QListView
.
IconMode
)
self
.
__ui
.
setSpacing
(
15
)
self
.
__ui
.
setMovement
(
QtWidgets
.
QListView
.
Static
)
self
.
__ui
.
setSelectionMode
(
QtWidgets
.
QAbstractItemView
.
ExtendedSelection
)
def
__initMenu
(
self
):
"""初始化图片列表界面菜单"""
utils
.
setMenu
(
self
.
__menu
,
"添加图片"
,
self
.
addImage
)
utils
.
setMenu
(
self
.
__menu
,
"移除图片"
,
self
.
removeImage
)
utils
.
setMenu
(
self
.
__menu
,
"编辑图片分类"
,
self
.
editImageClassify
)
self
.
__menu
.
addSeparator
()
utils
.
setMenu
(
self
.
__menu
,
"选择全部图片"
,
self
.
selectAllImage
)
utils
.
setMenu
(
self
.
__menu
,
"反向选择图片"
,
self
.
reverseSelectImage
)
utils
.
setMenu
(
self
.
__menu
,
"取消选择图片"
,
self
.
cancelSelectImage
)
self
.
__ui
.
setContextMenuPolicy
(
QtCore
.
Qt
.
CustomContextMenu
)
self
.
__ui
.
customContextMenuRequested
.
connect
(
self
.
__showMenu
)
def
__showMenu
(
self
,
pos
):
"""显示图片列表界面菜单"""
if
len
(
self
.
__imageListMgr
.
filePath
)
>
0
:
self
.
__menu
.
exec_
(
self
.
__ui
.
mapToGlobal
(
pos
))
def
__connectSignal
(
self
):
"""连接信号与槽"""
self
.
__ui
.
itemSelectionChanged
.
connect
(
self
.
onSelectionChanged
)
def
setImageScale
(
self
,
scale
:
int
):
"""设置图片大小"""
self
.
__imageScale
=
scale
size
=
QtCore
.
QSize
(
scale
*
BASE_IMAGE_SIZE
,
scale
*
BASE_IMAGE_SIZE
)
self
.
__ui
.
setIconSize
(
size
)
for
i
in
range
(
self
.
__ui
.
count
()):
item
=
self
.
__ui
.
item
(
i
)
item
.
setSizeHint
(
size
)
def
setImageList
(
self
,
classify
:
str
):
"""设置图片列表"""
size
=
QtCore
.
QSize
(
self
.
__imageScale
*
BASE_IMAGE_SIZE
,
self
.
__imageScale
*
BASE_IMAGE_SIZE
)
self
.
__selectedClassify
=
classify
image_list
=
self
.
__imageListMgr
.
imageList
(
classify
)
self
.
__ui
.
clear
()
count
=
0
for
i
in
image_list
:
item
=
QtWidgets
.
QListWidgetItem
(
self
.
__ui
)
item
.
setIcon
(
QtGui
.
QIcon
(
self
.
__imageListMgr
.
realPath
(
i
)))
item
.
setData
(
QtCore
.
Qt
.
UserRole
,
i
)
item
.
setSizeHint
(
size
)
self
.
__ui
.
addItem
(
item
)
count
+=
1
self
.
listCount
.
emit
(
count
)
def
clear
(
self
):
"""清除图片列表"""
self
.
__ui
.
clear
()
def
addImage
(
self
):
"""添加图片"""
if
not
os
.
path
.
exists
(
self
.
__imageListMgr
.
filePath
):
QtWidgets
.
QMessageBox
.
information
(
self
.
__parent
,
"提示"
,
"请先打开正确的图像库"
)
return
filter
=
"图片 (*.png *.jpg *.jpeg *.PNG *.JPG *.JPEG);;所有文件(*.*)"
dlg
=
QtWidgets
.
QFileDialog
(
self
.
__parent
)
dlg
.
setFileMode
(
QtWidgets
.
QFileDialog
.
ExistingFiles
)
# 多选文件
dlg
.
setViewMode
(
QtWidgets
.
QFileDialog
.
Detail
)
# 详细模式
file_paths
=
dlg
.
getOpenFileNames
(
filter
=
filter
)[
0
]
if
len
(
file_paths
)
==
0
:
return
image_list_dir
=
self
.
__imageListMgr
.
dirName
file_list
=
[]
for
path
in
file_paths
:
if
not
os
.
path
.
exists
(
path
):
continue
new_file
=
self
.
__copyToImagesDir
(
path
)
if
new_file
!=
""
and
image_list_dir
in
new_file
:
# 去掉 image_list_dir 的路径和斜杠
begin
=
len
(
image_list_dir
)
+
1
file_list
.
append
(
new_file
[
begin
:])
if
len
(
file_list
)
>
0
:
if
self
.
__selectedClassify
==
""
:
QtWidgets
.
QMessageBox
.
warning
(
self
.
__parent
,
"提示"
,
"请先选择分类"
)
return
new_list
=
self
.
__imageListMgr
.
imageList
(
self
.
__selectedClassify
)
+
file_list
self
.
__imageListMgr
.
resetImageList
(
self
.
__selectedClassify
,
new_list
)
self
.
setImageList
(
self
.
__selectedClassify
)
self
.
__imageListMgr
.
writeFile
()
def
__copyToImagesDir
(
self
,
image_path
:
str
):
md5
=
utils
.
fileMD5
(
image_path
)
file_ext
=
utils
.
fileExtension
(
image_path
)
to_dir
=
os
.
path
.
join
(
self
.
__imageListMgr
.
dirName
,
"images"
)
new_path
=
os
.
path
.
join
(
to_dir
,
md5
+
file_ext
)
if
os
.
path
.
exists
(
to_dir
):
utils
.
copyFile
(
image_path
,
new_path
)
return
new_path
else
:
return
""
def
removeImage
(
self
):
"""移除图片"""
if
not
os
.
path
.
exists
(
self
.
__imageListMgr
.
filePath
):
QtWidgets
.
QMessageBox
.
information
(
self
.
__parent
,
"提示"
,
"请先打开正确的图像库"
)
return
path_list
=
[]
image_list
=
self
.
__ui
.
selectedItems
()
if
len
(
image_list
)
==
0
:
return
question
=
QtWidgets
.
QMessageBox
.
question
(
self
.
__parent
,
"移除图片"
,
"确定移除所选图片吗?"
)
if
question
==
QtWidgets
.
QMessageBox
.
No
:
return
for
i
in
range
(
self
.
__ui
.
count
()):
item
=
self
.
__ui
.
item
(
i
)
img_path
=
item
.
data
(
QtCore
.
Qt
.
UserRole
)
if
not
item
.
isSelected
():
path_list
.
append
(
img_path
)
else
:
# 从磁盘上删除图片
utils
.
removeFile
(
os
.
path
.
join
(
self
.
__imageListMgr
.
dirName
,
img_path
))
self
.
__imageListMgr
.
resetImageList
(
self
.
__selectedClassify
,
path_list
)
self
.
setImageList
(
self
.
__selectedClassify
)
self
.
__imageListMgr
.
writeFile
()
def
editImageClassify
(
self
):
"""编辑图片分类"""
old_classify
=
self
.
__selectedClassify
dlg
=
imageeditclassifydialog
.
ImageEditClassifyDialog
(
parent
=
self
.
__parent
,
old_classify
=
old_classify
,
classify_list
=
self
.
__imageListMgr
.
classifyList
)
result
=
dlg
.
exec_
()
new_classify
=
dlg
.
newClassify
if
result
==
QtWidgets
.
QDialog
.
Accepted
\
and
new_classify
!=
old_classify
\
and
new_classify
!=
""
:
self
.
__moveImage
(
old_classify
,
new_classify
)
self
.
__imageListMgr
.
writeFile
()
def
__moveImage
(
self
,
old_classify
,
new_classify
):
"""移动图片"""
keep_list
=
[]
is_selected
=
False
move_list
=
self
.
__imageListMgr
.
imageList
(
new_classify
)
for
i
in
range
(
self
.
__ui
.
count
()):
item
=
self
.
__ui
.
item
(
i
)
txt
=
item
.
data
(
QtCore
.
Qt
.
UserRole
)
if
item
.
isSelected
():
move_list
.
append
(
txt
)
is_selected
=
True
else
:
keep_list
.
append
(
txt
)
if
is_selected
:
self
.
__imageListMgr
.
resetImageList
(
new_classify
,
move_list
)
self
.
__imageListMgr
.
resetImageList
(
old_classify
,
keep_list
)
self
.
setImageList
(
old_classify
)
def
selectAllImage
(
self
):
"""选择所有图片"""
self
.
__ui
.
selectAll
()
def
reverseSelectImage
(
self
):
"""反向选择图片"""
for
i
in
range
(
self
.
__ui
.
count
()):
item
=
self
.
__ui
.
item
(
i
)
item
.
setSelected
(
not
item
.
isSelected
())
def
cancelSelectImage
(
self
):
"""取消选择图片"""
self
.
__ui
.
clearSelection
()
def
onSelectionChanged
(
self
):
"""选择图像该变,发送选择的数量信号"""
count
=
len
(
self
.
__ui
.
selectedItems
())
self
.
selectedCount
.
emit
(
count
)
deploy/shitu_index_manager/mod/imageeditclassifydialog.py
0 → 100644
浏览文件 @
f64bec7f
import
os
from
PyQt5
import
QtCore
,
QtGui
,
QtWidgets
from
mod
import
image_list_manager
from
mod
import
ui_imageeditclassifydialog
from
mod
import
utils
class
ImageEditClassifyDialog
(
QtWidgets
.
QDialog
):
"""图像编辑分类对话框"""
def
__init__
(
self
,
parent
,
old_classify
,
classify_list
):
super
(
ImageEditClassifyDialog
,
self
).
__init__
(
parent
)
self
.
ui
=
mod
.
ui_imageeditclassifydialog
.
Ui_Dialog
()
self
.
ui
.
setupUi
(
self
)
# 初始化主窗口界面
self
.
__oldClassify
=
old_classify
self
.
__classifyList
=
classify_list
self
.
__newClassify
=
""
self
.
__searchResult
=
[]
self
.
__initUi
()
self
.
__connectSignal
()
@
property
def
newClassify
(
self
):
return
self
.
__newClassify
def
__initUi
(
self
):
self
.
ui
.
oldLineEdit
.
setText
(
self
.
__oldClassify
)
self
.
__setClassifyList
(
self
.
__classifyList
)
self
.
ui
.
classifyListView
.
setEditTriggers
(
QtWidgets
.
QAbstractItemView
.
NoEditTriggers
)
def
__connectSignal
(
self
):
self
.
ui
.
classifyListView
.
clicked
.
connect
(
self
.
selectedListView
)
self
.
ui
.
searchButton
.
clicked
.
connect
(
self
.
searchClassify
)
def
__setClassifyList
(
self
,
classify_list
):
list_model
=
QtCore
.
QStringListModel
(
classify_list
)
self
.
ui
.
classifyListView
.
setModel
(
list_model
)
def
selectedListView
(
self
,
index
):
if
not
self
.
ui
.
classifyListView
.
currentIndex
().
isValid
():
return
txt
=
index
.
data
()
self
.
ui
.
newLineEdit
.
setText
(
txt
)
self
.
__newClassify
=
txt
def
searchClassify
(
self
):
txt
=
self
.
ui
.
searchWordLineEdit
.
text
()
self
.
__searchResult
.
clear
()
for
classify
in
self
.
__classifyList
:
if
txt
in
classify
:
self
.
__searchResult
.
append
(
classify
)
self
.
__setClassifyList
(
self
.
__searchResult
)
deploy/shitu_index_manager/mod/index_http_client.py
0 → 100644
浏览文件 @
f64bec7f
import
json
import
os
import
urllib3
import
urllib.parse
class
IndexHttpClient
():
"""索引库客户端,使用 urllib3 连接,使用 urllib.parse 进行 url 编码"""
def
__init__
(
self
,
host
:
str
,
port
:
int
):
self
.
__host
=
host
self
.
__port
=
port
self
.
__http
=
urllib3
.
PoolManager
()
self
.
__headers
=
{
"Content-type"
:
"application/json"
}
def
url
(
self
):
return
"http://{}:{}"
.
format
(
self
.
__host
,
self
.
__port
)
def
new_index
(
self
,
image_list_path
:
str
,
index_root_path
:
str
,
index_method
=
"HNSW32"
,
force
=
False
):
"""新建 重建 库"""
if
index_method
not
in
[
"HNSW32"
,
"FLAT"
,
"IVF"
]:
raise
Exception
(
"index_method 必须是 HNSW32, FLAT, IVF,实际值为:{}"
.
format
(
index_method
))
params
=
{
"image_list_path"
:
image_list_path
,
\
"index_root_path"
:
index_root_path
,
\
"index_method"
:
index_method
,
\
"force"
:
force
}
return
self
.
__post
(
self
.
url
()
+
"/new_index?"
,
params
)
def
open_index
(
self
,
index_root_path
:
str
,
image_list_path
:
str
):
"""打开库"""
params
=
{
"index_root_path"
:
index_root_path
,
"image_list_path"
:
image_list_path
}
return
self
.
__post
(
self
.
url
()
+
"/open_index?"
,
params
)
def
update_index
(
self
,
image_list_path
:
str
,
index_root_path
:
str
):
"""更新索引库"""
params
=
{
"image_list_path"
:
image_list_path
,
\
"index_root_path"
:
index_root_path
}
return
self
.
__post
(
self
.
url
()
+
"/update_index?"
,
params
)
def
__post
(
self
,
url
:
str
,
params
:
dict
):
"""发送 url 并接收数据"""
http
=
self
.
__http
encode_params
=
urllib
.
parse
.
urlencode
(
params
)
get_url
=
url
+
encode_params
req
=
http
.
request
(
"GET"
,
get_url
,
headers
=
self
.
__headers
)
result
=
json
.
loads
(
req
.
data
)
if
isinstance
(
result
,
str
):
result
=
eval
(
result
)
msg
=
result
[
"error_message"
]
if
msg
!=
None
and
len
(
msg
)
==
0
:
msg
=
None
return
msg
deploy/shitu_index_manager/mod/mainwindow.py
0 → 100644
浏览文件 @
f64bec7f
此差异已折叠。
点击以展开。
deploy/shitu_index_manager/mod/ui_addclassifydialog.py
0 → 100644
浏览文件 @
f64bec7f
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui/AddClassifyDialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.5
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from
PyQt5
import
QtCore
,
QtGui
,
QtWidgets
class
Ui_AddClassifyDialog
(
object
):
def
setupUi
(
self
,
AddClassifyDialog
):
AddClassifyDialog
.
setObjectName
(
"AddClassifyDialog"
)
AddClassifyDialog
.
resize
(
286
,
127
)
AddClassifyDialog
.
setModal
(
True
)
self
.
verticalLayout
=
QtWidgets
.
QVBoxLayout
(
AddClassifyDialog
)
self
.
verticalLayout
.
setObjectName
(
"verticalLayout"
)
self
.
label
=
QtWidgets
.
QLabel
(
AddClassifyDialog
)
self
.
label
.
setObjectName
(
"label"
)
self
.
verticalLayout
.
addWidget
(
self
.
label
)
self
.
lineEdit
=
QtWidgets
.
QLineEdit
(
AddClassifyDialog
)
self
.
lineEdit
.
setObjectName
(
"lineEdit"
)
self
.
verticalLayout
.
addWidget
(
self
.
lineEdit
)
spacerItem
=
QtWidgets
.
QSpacerItem
(
20
,
11
,
QtWidgets
.
QSizePolicy
.
Minimum
,
QtWidgets
.
QSizePolicy
.
Expanding
)
self
.
verticalLayout
.
addItem
(
spacerItem
)
self
.
buttonBox
=
QtWidgets
.
QDialogButtonBox
(
AddClassifyDialog
)
self
.
buttonBox
.
setOrientation
(
QtCore
.
Qt
.
Horizontal
)
self
.
buttonBox
.
setStandardButtons
(
QtWidgets
.
QDialogButtonBox
.
Cancel
|
QtWidgets
.
QDialogButtonBox
.
Ok
)
self
.
buttonBox
.
setObjectName
(
"buttonBox"
)
self
.
verticalLayout
.
addWidget
(
self
.
buttonBox
)
self
.
retranslateUi
(
AddClassifyDialog
)
self
.
buttonBox
.
accepted
.
connect
(
AddClassifyDialog
.
accept
)
self
.
buttonBox
.
rejected
.
connect
(
AddClassifyDialog
.
reject
)
QtCore
.
QMetaObject
.
connectSlotsByName
(
AddClassifyDialog
)
def
retranslateUi
(
self
,
AddClassifyDialog
):
_translate
=
QtCore
.
QCoreApplication
.
translate
AddClassifyDialog
.
setWindowTitle
(
_translate
(
"AddClassifyDialog"
,
"添加分类"
))
self
.
label
.
setText
(
_translate
(
"AddClassifyDialog"
,
"分类名称"
))
if
__name__
==
"__main__"
:
import
sys
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
AddClassifyDialog
=
QtWidgets
.
QDialog
()
ui
=
Ui_AddClassifyDialog
()
ui
.
setupUi
(
AddClassifyDialog
)
AddClassifyDialog
.
show
()
sys
.
exit
(
app
.
exec_
())
deploy/shitu_index_manager/mod/ui_imageeditclassifydialog.py
0 → 100644
浏览文件 @
f64bec7f
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui/ImageEditClassifyDialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.5
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from
PyQt5
import
QtCore
,
QtGui
,
QtWidgets
class
Ui_Dialog
(
object
):
def
setupUi
(
self
,
Dialog
):
Dialog
.
setObjectName
(
"Dialog"
)
Dialog
.
resize
(
414
,
415
)
Dialog
.
setMinimumSize
(
QtCore
.
QSize
(
0
,
0
))
self
.
verticalLayout
=
QtWidgets
.
QVBoxLayout
(
Dialog
)
self
.
verticalLayout
.
setObjectName
(
"verticalLayout"
)
self
.
label
=
QtWidgets
.
QLabel
(
Dialog
)
self
.
label
.
setObjectName
(
"label"
)
self
.
verticalLayout
.
addWidget
(
self
.
label
)
self
.
oldLineEdit
=
QtWidgets
.
QLineEdit
(
Dialog
)
self
.
oldLineEdit
.
setEnabled
(
False
)
self
.
oldLineEdit
.
setObjectName
(
"oldLineEdit"
)
self
.
verticalLayout
.
addWidget
(
self
.
oldLineEdit
)
self
.
label_2
=
QtWidgets
.
QLabel
(
Dialog
)
self
.
label_2
.
setObjectName
(
"label_2"
)
self
.
verticalLayout
.
addWidget
(
self
.
label_2
)
self
.
newLineEdit
=
QtWidgets
.
QLineEdit
(
Dialog
)
self
.
newLineEdit
.
setEnabled
(
False
)
self
.
newLineEdit
.
setObjectName
(
"newLineEdit"
)
self
.
verticalLayout
.
addWidget
(
self
.
newLineEdit
)
self
.
horizontalLayout
=
QtWidgets
.
QHBoxLayout
()
self
.
horizontalLayout
.
setObjectName
(
"horizontalLayout"
)
self
.
searchWordLineEdit
=
QtWidgets
.
QLineEdit
(
Dialog
)
self
.
searchWordLineEdit
.
setObjectName
(
"searchWordLineEdit"
)
self
.
horizontalLayout
.
addWidget
(
self
.
searchWordLineEdit
)
self
.
searchButton
=
QtWidgets
.
QPushButton
(
Dialog
)
self
.
searchButton
.
setObjectName
(
"searchButton"
)
self
.
horizontalLayout
.
addWidget
(
self
.
searchButton
)
self
.
verticalLayout
.
addLayout
(
self
.
horizontalLayout
)
self
.
classifyListView
=
QtWidgets
.
QListView
(
Dialog
)
self
.
classifyListView
.
setEnabled
(
True
)
self
.
classifyListView
.
setMinimumSize
(
QtCore
.
QSize
(
400
,
200
))
self
.
classifyListView
.
setObjectName
(
"classifyListView"
)
self
.
verticalLayout
.
addWidget
(
self
.
classifyListView
)
self
.
buttonBox
=
QtWidgets
.
QDialogButtonBox
(
Dialog
)
self
.
buttonBox
.
setOrientation
(
QtCore
.
Qt
.
Horizontal
)
self
.
buttonBox
.
setStandardButtons
(
QtWidgets
.
QDialogButtonBox
.
Cancel
|
QtWidgets
.
QDialogButtonBox
.
Ok
)
self
.
buttonBox
.
setObjectName
(
"buttonBox"
)
self
.
verticalLayout
.
addWidget
(
self
.
buttonBox
)
self
.
retranslateUi
(
Dialog
)
self
.
buttonBox
.
accepted
.
connect
(
Dialog
.
accept
)
self
.
buttonBox
.
rejected
.
connect
(
Dialog
.
reject
)
QtCore
.
QMetaObject
.
connectSlotsByName
(
Dialog
)
def
retranslateUi
(
self
,
Dialog
):
_translate
=
QtCore
.
QCoreApplication
.
translate
Dialog
.
setWindowTitle
(
_translate
(
"Dialog"
,
"编辑图像分类"
))
self
.
label
.
setText
(
_translate
(
"Dialog"
,
"原分类"
))
self
.
label_2
.
setText
(
_translate
(
"Dialog"
,
"新分类"
))
self
.
searchButton
.
setText
(
_translate
(
"Dialog"
,
"查找"
))
if
__name__
==
"__main__"
:
import
sys
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
Dialog
=
QtWidgets
.
QDialog
()
ui
=
Ui_Dialog
()
ui
.
setupUi
(
Dialog
)
Dialog
.
show
()
sys
.
exit
(
app
.
exec_
())
deploy/shitu_index_manager/mod/ui_mainwindow.py
0 → 100644
浏览文件 @
f64bec7f
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui/MainWindow.ui'
#
# Created by: PyQt5 UI code generator 5.15.5
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from
PyQt5
import
QtCore
,
QtGui
,
QtWidgets
class
Ui_MainWindow
(
object
):
def
setupUi
(
self
,
MainWindow
):
MainWindow
.
setObjectName
(
"MainWindow"
)
MainWindow
.
resize
(
833
,
538
)
MainWindow
.
setMinimumSize
(
QtCore
.
QSize
(
0
,
0
))
self
.
centralwidget
=
QtWidgets
.
QWidget
(
MainWindow
)
self
.
centralwidget
.
setObjectName
(
"centralwidget"
)
self
.
verticalLayout_3
=
QtWidgets
.
QVBoxLayout
(
self
.
centralwidget
)
self
.
verticalLayout_3
.
setObjectName
(
"verticalLayout_3"
)
self
.
horizontalLayout_3
=
QtWidgets
.
QHBoxLayout
()
self
.
horizontalLayout_3
.
setObjectName
(
"horizontalLayout_3"
)
self
.
appMenuBtn
=
QtWidgets
.
QToolButton
(
self
.
centralwidget
)
self
.
appMenuBtn
.
setObjectName
(
"appMenuBtn"
)
self
.
horizontalLayout_3
.
addWidget
(
self
.
appMenuBtn
)
self
.
saveImageLibraryBtn
=
QtWidgets
.
QToolButton
(
self
.
centralwidget
)
self
.
saveImageLibraryBtn
.
setObjectName
(
"saveImageLibraryBtn"
)
self
.
horizontalLayout_3
.
addWidget
(
self
.
saveImageLibraryBtn
)
self
.
addClassifyBtn
=
QtWidgets
.
QToolButton
(
self
.
centralwidget
)
self
.
addClassifyBtn
.
setObjectName
(
"addClassifyBtn"
)
self
.
horizontalLayout_3
.
addWidget
(
self
.
addClassifyBtn
)
self
.
removeClassifyBtn
=
QtWidgets
.
QToolButton
(
self
.
centralwidget
)
self
.
removeClassifyBtn
.
setObjectName
(
"removeClassifyBtn"
)
self
.
horizontalLayout_3
.
addWidget
(
self
.
removeClassifyBtn
)
spacerItem
=
QtWidgets
.
QSpacerItem
(
40
,
20
,
QtWidgets
.
QSizePolicy
.
Expanding
,
QtWidgets
.
QSizePolicy
.
Minimum
)
self
.
horizontalLayout_3
.
addItem
(
spacerItem
)
self
.
imageScaleSlider
=
QtWidgets
.
QSlider
(
self
.
centralwidget
)
self
.
imageScaleSlider
.
setMaximumSize
(
QtCore
.
QSize
(
400
,
16777215
))
self
.
imageScaleSlider
.
setMinimum
(
1
)
self
.
imageScaleSlider
.
setMaximum
(
8
)
self
.
imageScaleSlider
.
setPageStep
(
2
)
self
.
imageScaleSlider
.
setOrientation
(
QtCore
.
Qt
.
Horizontal
)
self
.
imageScaleSlider
.
setObjectName
(
"imageScaleSlider"
)
self
.
horizontalLayout_3
.
addWidget
(
self
.
imageScaleSlider
)
self
.
verticalLayout_3
.
addLayout
(
self
.
horizontalLayout_3
)
self
.
splitter
=
QtWidgets
.
QSplitter
(
self
.
centralwidget
)
sizePolicy
=
QtWidgets
.
QSizePolicy
(
QtWidgets
.
QSizePolicy
.
Expanding
,
QtWidgets
.
QSizePolicy
.
Expanding
)
sizePolicy
.
setHorizontalStretch
(
0
)
sizePolicy
.
setVerticalStretch
(
0
)
sizePolicy
.
setHeightForWidth
(
self
.
splitter
.
sizePolicy
().
hasHeightForWidth
())
self
.
splitter
.
setSizePolicy
(
sizePolicy
)
self
.
splitter
.
setOrientation
(
QtCore
.
Qt
.
Horizontal
)
self
.
splitter
.
setObjectName
(
"splitter"
)
self
.
widget
=
QtWidgets
.
QWidget
(
self
.
splitter
)
self
.
widget
.
setObjectName
(
"widget"
)
self
.
verticalLayout_2
=
QtWidgets
.
QVBoxLayout
(
self
.
widget
)
self
.
verticalLayout_2
.
setContentsMargins
(
0
,
0
,
0
,
0
)
self
.
verticalLayout_2
.
setObjectName
(
"verticalLayout_2"
)
self
.
horizontalLayout
=
QtWidgets
.
QHBoxLayout
()
self
.
horizontalLayout
.
setObjectName
(
"horizontalLayout"
)
self
.
searchClassifyHistoryCmb
=
QtWidgets
.
QComboBox
(
self
.
widget
)
sizePolicy
=
QtWidgets
.
QSizePolicy
(
QtWidgets
.
QSizePolicy
.
Expanding
,
QtWidgets
.
QSizePolicy
.
Fixed
)
sizePolicy
.
setHorizontalStretch
(
0
)
sizePolicy
.
setVerticalStretch
(
0
)
sizePolicy
.
setHeightForWidth
(
self
.
searchClassifyHistoryCmb
.
sizePolicy
().
hasHeightForWidth
())
self
.
searchClassifyHistoryCmb
.
setSizePolicy
(
sizePolicy
)
self
.
searchClassifyHistoryCmb
.
setEditable
(
True
)
self
.
searchClassifyHistoryCmb
.
setObjectName
(
"searchClassifyHistoryCmb"
)
self
.
horizontalLayout
.
addWidget
(
self
.
searchClassifyHistoryCmb
)
self
.
searchClassifyBtn
=
QtWidgets
.
QToolButton
(
self
.
widget
)
self
.
searchClassifyBtn
.
setObjectName
(
"searchClassifyBtn"
)
self
.
horizontalLayout
.
addWidget
(
self
.
searchClassifyBtn
)
self
.
verticalLayout_2
.
addLayout
(
self
.
horizontalLayout
)
self
.
classifyListView
=
QtWidgets
.
QListView
(
self
.
widget
)
sizePolicy
=
QtWidgets
.
QSizePolicy
(
QtWidgets
.
QSizePolicy
.
Expanding
,
QtWidgets
.
QSizePolicy
.
Expanding
)
sizePolicy
.
setHorizontalStretch
(
0
)
sizePolicy
.
setVerticalStretch
(
0
)
sizePolicy
.
setHeightForWidth
(
self
.
classifyListView
.
sizePolicy
().
hasHeightForWidth
())
self
.
classifyListView
.
setSizePolicy
(
sizePolicy
)
self
.
classifyListView
.
setMinimumSize
(
QtCore
.
QSize
(
200
,
0
))
self
.
classifyListView
.
setEditTriggers
(
QtWidgets
.
QAbstractItemView
.
NoEditTriggers
)
self
.
classifyListView
.
setObjectName
(
"classifyListView"
)
self
.
verticalLayout_2
.
addWidget
(
self
.
classifyListView
)
self
.
widget1
=
QtWidgets
.
QWidget
(
self
.
splitter
)
self
.
widget1
.
setObjectName
(
"widget1"
)
self
.
verticalLayout
=
QtWidgets
.
QVBoxLayout
(
self
.
widget1
)
self
.
verticalLayout
.
setContentsMargins
(
0
,
0
,
0
,
0
)
self
.
verticalLayout
.
setObjectName
(
"verticalLayout"
)
self
.
horizontalLayout_2
=
QtWidgets
.
QHBoxLayout
()
self
.
horizontalLayout_2
.
setObjectName
(
"horizontalLayout_2"
)
self
.
addImageBtn
=
QtWidgets
.
QToolButton
(
self
.
widget1
)
self
.
addImageBtn
.
setObjectName
(
"addImageBtn"
)
self
.
horizontalLayout_2
.
addWidget
(
self
.
addImageBtn
)
self
.
removeImageBtn
=
QtWidgets
.
QToolButton
(
self
.
widget1
)
self
.
removeImageBtn
.
setObjectName
(
"removeImageBtn"
)
self
.
horizontalLayout_2
.
addWidget
(
self
.
removeImageBtn
)
spacerItem1
=
QtWidgets
.
QSpacerItem
(
40
,
20
,
QtWidgets
.
QSizePolicy
.
Expanding
,
QtWidgets
.
QSizePolicy
.
Minimum
)
self
.
horizontalLayout_2
.
addItem
(
spacerItem1
)
self
.
verticalLayout
.
addLayout
(
self
.
horizontalLayout_2
)
self
.
imageListWidget
=
QtWidgets
.
QListWidget
(
self
.
widget1
)
sizePolicy
=
QtWidgets
.
QSizePolicy
(
QtWidgets
.
QSizePolicy
.
Expanding
,
QtWidgets
.
QSizePolicy
.
Expanding
)
sizePolicy
.
setHorizontalStretch
(
0
)
sizePolicy
.
setVerticalStretch
(
0
)
sizePolicy
.
setHeightForWidth
(
self
.
imageListWidget
.
sizePolicy
().
hasHeightForWidth
())
self
.
imageListWidget
.
setSizePolicy
(
sizePolicy
)
self
.
imageListWidget
.
setMinimumSize
(
QtCore
.
QSize
(
200
,
0
))
self
.
imageListWidget
.
setStyleSheet
(
"QListWidget::Item:hover{background:skyblue;padding-top:0px; padding-bottom:0px;}
\n
"
"QListWidget::item:selected{background:rgb(245, 121, 0); color:red;}"
)
self
.
imageListWidget
.
setObjectName
(
"imageListWidget"
)
self
.
verticalLayout
.
addWidget
(
self
.
imageListWidget
)
self
.
verticalLayout_3
.
addWidget
(
self
.
splitter
)
MainWindow
.
setCentralWidget
(
self
.
centralwidget
)
self
.
statusbar
=
QtWidgets
.
QStatusBar
(
MainWindow
)
self
.
statusbar
.
setObjectName
(
"statusbar"
)
MainWindow
.
setStatusBar
(
self
.
statusbar
)
self
.
retranslateUi
(
MainWindow
)
QtCore
.
QMetaObject
.
connectSlotsByName
(
MainWindow
)
def
retranslateUi
(
self
,
MainWindow
):
_translate
=
QtCore
.
QCoreApplication
.
translate
MainWindow
.
setWindowTitle
(
_translate
(
"MainWindow"
,
"识图图像库管理"
))
self
.
appMenuBtn
.
setText
(
_translate
(
"MainWindow"
,
"..."
))
self
.
saveImageLibraryBtn
.
setText
(
_translate
(
"MainWindow"
,
"..."
))
self
.
addClassifyBtn
.
setText
(
_translate
(
"MainWindow"
,
"..."
))
self
.
removeClassifyBtn
.
setText
(
_translate
(
"MainWindow"
,
"..."
))
self
.
searchClassifyBtn
.
setText
(
_translate
(
"MainWindow"
,
"..."
))
self
.
addImageBtn
.
setText
(
_translate
(
"MainWindow"
,
"..."
))
self
.
removeImageBtn
.
setText
(
_translate
(
"MainWindow"
,
"..."
))
if
__name__
==
"__main__"
:
import
sys
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
MainWindow
=
QtWidgets
.
QMainWindow
()
ui
=
Ui_MainWindow
()
ui
.
setupUi
(
MainWindow
)
MainWindow
.
show
()
sys
.
exit
(
app
.
exec_
())
deploy/shitu_index_manager/mod/ui_newlibrarydialog.py
0 → 100644
浏览文件 @
f64bec7f
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui/NewlibraryDialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.5
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from
PyQt5
import
QtCore
,
QtGui
,
QtWidgets
class
Ui_NewlibraryDialog
(
object
):
def
setupUi
(
self
,
NewlibraryDialog
):
NewlibraryDialog
.
setObjectName
(
"NewlibraryDialog"
)
NewlibraryDialog
.
resize
(
414
,
230
)
self
.
verticalLayout
=
QtWidgets
.
QVBoxLayout
(
NewlibraryDialog
)
self
.
verticalLayout
.
setObjectName
(
"verticalLayout"
)
self
.
label
=
QtWidgets
.
QLabel
(
NewlibraryDialog
)
self
.
label
.
setObjectName
(
"label"
)
self
.
verticalLayout
.
addWidget
(
self
.
label
)
self
.
indexMethodCmb
=
QtWidgets
.
QComboBox
(
NewlibraryDialog
)
self
.
indexMethodCmb
.
setEnabled
(
True
)
self
.
indexMethodCmb
.
setObjectName
(
"indexMethodCmb"
)
self
.
indexMethodCmb
.
addItem
(
""
)
self
.
indexMethodCmb
.
addItem
(
""
)
self
.
indexMethodCmb
.
addItem
(
""
)
self
.
verticalLayout
.
addWidget
(
self
.
indexMethodCmb
)
self
.
resetCheckBox
=
QtWidgets
.
QCheckBox
(
NewlibraryDialog
)
self
.
resetCheckBox
.
setObjectName
(
"resetCheckBox"
)
self
.
verticalLayout
.
addWidget
(
self
.
resetCheckBox
)
spacerItem
=
QtWidgets
.
QSpacerItem
(
20
,
80
,
QtWidgets
.
QSizePolicy
.
Minimum
,
QtWidgets
.
QSizePolicy
.
Expanding
)
self
.
verticalLayout
.
addItem
(
spacerItem
)
self
.
buttonBox
=
QtWidgets
.
QDialogButtonBox
(
NewlibraryDialog
)
self
.
buttonBox
.
setOrientation
(
QtCore
.
Qt
.
Horizontal
)
self
.
buttonBox
.
setStandardButtons
(
QtWidgets
.
QDialogButtonBox
.
Cancel
|
QtWidgets
.
QDialogButtonBox
.
Ok
)
self
.
buttonBox
.
setObjectName
(
"buttonBox"
)
self
.
verticalLayout
.
addWidget
(
self
.
buttonBox
)
self
.
retranslateUi
(
NewlibraryDialog
)
self
.
indexMethodCmb
.
setCurrentIndex
(
0
)
self
.
buttonBox
.
accepted
.
connect
(
NewlibraryDialog
.
accept
)
self
.
buttonBox
.
rejected
.
connect
(
NewlibraryDialog
.
reject
)
QtCore
.
QMetaObject
.
connectSlotsByName
(
NewlibraryDialog
)
def
retranslateUi
(
self
,
NewlibraryDialog
):
_translate
=
QtCore
.
QCoreApplication
.
translate
NewlibraryDialog
.
setWindowTitle
(
_translate
(
"NewlibraryDialog"
,
"新建/重建 索引"
))
self
.
label
.
setText
(
_translate
(
"NewlibraryDialog"
,
"索引方式"
))
self
.
indexMethodCmb
.
setItemText
(
0
,
_translate
(
"NewlibraryDialog"
,
"HNSW32"
))
self
.
indexMethodCmb
.
setItemText
(
1
,
_translate
(
"NewlibraryDialog"
,
"FLAT"
))
self
.
indexMethodCmb
.
setItemText
(
2
,
_translate
(
"NewlibraryDialog"
,
"IVF"
))
self
.
resetCheckBox
.
setText
(
_translate
(
"NewlibraryDialog"
,
"重建索引,警告:会覆盖原索引"
))
if
__name__
==
"__main__"
:
import
sys
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
NewlibraryDialog
=
QtWidgets
.
QDialog
()
ui
=
Ui_NewlibraryDialog
()
ui
.
setupUi
(
NewlibraryDialog
)
NewlibraryDialog
.
show
()
sys
.
exit
(
app
.
exec_
())
deploy/shitu_index_manager/mod/ui_renameclassifydialog.py
0 → 100644
浏览文件 @
f64bec7f
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui/RenameClassifyDialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.5
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from
PyQt5
import
QtCore
,
QtGui
,
QtWidgets
class
Ui_RenameClassifyDialog
(
object
):
def
setupUi
(
self
,
RenameClassifyDialog
):
RenameClassifyDialog
.
setObjectName
(
"RenameClassifyDialog"
)
RenameClassifyDialog
.
resize
(
342
,
194
)
self
.
verticalLayout
=
QtWidgets
.
QVBoxLayout
(
RenameClassifyDialog
)
self
.
verticalLayout
.
setObjectName
(
"verticalLayout"
)
self
.
oldlabel
=
QtWidgets
.
QLabel
(
RenameClassifyDialog
)
self
.
oldlabel
.
setObjectName
(
"oldlabel"
)
self
.
verticalLayout
.
addWidget
(
self
.
oldlabel
)
self
.
oldNameLineEdit
=
QtWidgets
.
QLineEdit
(
RenameClassifyDialog
)
self
.
oldNameLineEdit
.
setEnabled
(
False
)
self
.
oldNameLineEdit
.
setObjectName
(
"oldNameLineEdit"
)
self
.
verticalLayout
.
addWidget
(
self
.
oldNameLineEdit
)
self
.
newlabel
=
QtWidgets
.
QLabel
(
RenameClassifyDialog
)
self
.
newlabel
.
setObjectName
(
"newlabel"
)
self
.
verticalLayout
.
addWidget
(
self
.
newlabel
)
self
.
newNameLineEdit
=
QtWidgets
.
QLineEdit
(
RenameClassifyDialog
)
self
.
newNameLineEdit
.
setObjectName
(
"newNameLineEdit"
)
self
.
verticalLayout
.
addWidget
(
self
.
newNameLineEdit
)
spacerItem
=
QtWidgets
.
QSpacerItem
(
20
,
14
,
QtWidgets
.
QSizePolicy
.
Minimum
,
QtWidgets
.
QSizePolicy
.
Expanding
)
self
.
verticalLayout
.
addItem
(
spacerItem
)
self
.
buttonBox
=
QtWidgets
.
QDialogButtonBox
(
RenameClassifyDialog
)
self
.
buttonBox
.
setOrientation
(
QtCore
.
Qt
.
Horizontal
)
self
.
buttonBox
.
setStandardButtons
(
QtWidgets
.
QDialogButtonBox
.
Cancel
|
QtWidgets
.
QDialogButtonBox
.
Ok
)
self
.
buttonBox
.
setObjectName
(
"buttonBox"
)
self
.
verticalLayout
.
addWidget
(
self
.
buttonBox
)
self
.
retranslateUi
(
RenameClassifyDialog
)
self
.
buttonBox
.
accepted
.
connect
(
RenameClassifyDialog
.
accept
)
self
.
buttonBox
.
rejected
.
connect
(
RenameClassifyDialog
.
reject
)
QtCore
.
QMetaObject
.
connectSlotsByName
(
RenameClassifyDialog
)
def
retranslateUi
(
self
,
RenameClassifyDialog
):
_translate
=
QtCore
.
QCoreApplication
.
translate
RenameClassifyDialog
.
setWindowTitle
(
_translate
(
"RenameClassifyDialog"
,
"重命名分类"
))
self
.
oldlabel
.
setText
(
_translate
(
"RenameClassifyDialog"
,
"原名称"
))
self
.
newlabel
.
setText
(
_translate
(
"RenameClassifyDialog"
,
"新名称"
))
if
__name__
==
"__main__"
:
import
sys
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
RenameClassifyDialog
=
QtWidgets
.
QDialog
()
ui
=
Ui_RenameClassifyDialog
()
ui
.
setupUi
(
RenameClassifyDialog
)
RenameClassifyDialog
.
show
()
sys
.
exit
(
app
.
exec_
())
deploy/shitu_index_manager/mod/ui_waitdialog.py
0 → 100644
浏览文件 @
f64bec7f
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui/WaitDialog.ui'
#
# Created by: PyQt5 UI code generator 5.15.5
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from
PyQt5
import
QtCore
,
QtGui
,
QtWidgets
class
Ui_WaitDialog
(
object
):
def
setupUi
(
self
,
WaitDialog
):
WaitDialog
.
setObjectName
(
"WaitDialog"
)
WaitDialog
.
setWindowModality
(
QtCore
.
Qt
.
NonModal
)
WaitDialog
.
resize
(
324
,
78
)
self
.
verticalLayout
=
QtWidgets
.
QVBoxLayout
(
WaitDialog
)
self
.
verticalLayout
.
setObjectName
(
"verticalLayout"
)
self
.
msgLabel
=
QtWidgets
.
QLabel
(
WaitDialog
)
self
.
msgLabel
.
setObjectName
(
"msgLabel"
)
self
.
verticalLayout
.
addWidget
(
self
.
msgLabel
)
self
.
progressBar
=
QtWidgets
.
QProgressBar
(
WaitDialog
)
self
.
progressBar
.
setMaximum
(
0
)
self
.
progressBar
.
setProperty
(
"value"
,
-
1
)
self
.
progressBar
.
setObjectName
(
"progressBar"
)
self
.
verticalLayout
.
addWidget
(
self
.
progressBar
)
spacerItem
=
QtWidgets
.
QSpacerItem
(
20
,
1
,
QtWidgets
.
QSizePolicy
.
Minimum
,
QtWidgets
.
QSizePolicy
.
Expanding
)
self
.
verticalLayout
.
addItem
(
spacerItem
)
self
.
retranslateUi
(
WaitDialog
)
QtCore
.
QMetaObject
.
connectSlotsByName
(
WaitDialog
)
def
retranslateUi
(
self
,
WaitDialog
):
_translate
=
QtCore
.
QCoreApplication
.
translate
WaitDialog
.
setWindowTitle
(
_translate
(
"WaitDialog"
,
"请等待"
))
self
.
msgLabel
.
setText
(
_translate
(
"WaitDialog"
,
"正在更新索引库,请等待。。。"
))
if
__name__
==
"__main__"
:
import
sys
app
=
QtWidgets
.
QApplication
(
sys
.
argv
)
WaitDialog
=
QtWidgets
.
QDialog
()
ui
=
Ui_WaitDialog
()
ui
.
setupUi
(
WaitDialog
)
WaitDialog
.
show
()
sys
.
exit
(
app
.
exec_
())
deploy/shitu_index_manager/mod/utils.py
0 → 100644
浏览文件 @
f64bec7f
import
os
import
sys
from
PyQt5
import
QtCore
,
QtGui
,
QtWidgets
import
hashlib
import
shutil
from
mod
import
image_list_manager
def
setMenu
(
menu
:
QtWidgets
.
QMenu
,
text
:
str
,
triggered
):
"""设置菜单"""
action
=
menu
.
addAction
(
text
)
action
.
triggered
.
connect
(
triggered
)
def
fileMD5
(
file_path
:
str
):
"""计算文件的MD5值"""
md5
=
hashlib
.
md5
()
with
open
(
file_path
,
'rb'
)
as
f
:
md5
.
update
(
f
.
read
())
return
md5
.
hexdigest
().
lower
()
def
copyFile
(
from_path
:
str
,
to_path
:
str
):
"""复制文件"""
shutil
.
copyfile
(
from_path
,
to_path
)
return
os
.
path
.
exists
(
to_path
)
def
removeFile
(
file_path
:
str
):
"""删除文件"""
if
os
.
path
.
exists
(
file_path
):
os
.
remove
(
file_path
)
return
not
os
.
path
.
exists
(
file_path
)
def
fileExtension
(
file_path
:
str
):
"""获取文件的扩展名"""
return
os
.
path
.
splitext
(
file_path
)[
1
]
def
copyImageToDir
(
self
,
from_image_path
:
str
,
to_dir_path
:
str
):
"""复制图像文件到目标目录"""
if
not
os
.
path
.
exists
(
from_image_path
)
and
not
os
.
path
.
exists
(
to_dir_path
):
return
None
md5
=
fileMD5
(
from_image_path
)
file_ext
=
fileExtension
(
from_image_path
)
new_path
=
os
.
path
.
join
(
to_dir_path
,
md5
+
file_ext
)
copyFile
(
from_image_path
,
new_path
)
return
new_path
def
oneKeyImportFromFile
(
from_path
:
str
,
to_path
:
str
):
"""从其它图像库 from_path {image_list.txt} 导入到图像库 to_path {image_list.txt}"""
if
not
os
.
path
.
exists
(
from_path
)
or
not
os
.
path
.
exists
(
to_path
):
return
None
if
from_path
==
to_path
:
return
None
from_mgr
=
image_list_manager
.
ImageListManager
(
file_path
=
from_path
)
to_mgr
=
image_list_manager
.
ImageListManager
(
file_path
=
to_path
)
return
oneKeyImport
(
from_mgr
=
from_mgr
,
to_mgr
=
to_mgr
)
def
oneKeyImportFromDirs
(
from_dir
:
str
,
to_image_list_path
:
str
):
"""从其它图像库 from_dir 搜索子目录 导入到图像库 to_image_list_path"""
if
not
os
.
path
.
exists
(
from_dir
)
or
not
os
.
path
.
exists
(
to_image_list_path
):
return
None
if
from_dir
==
os
.
path
.
dirname
(
to_image_list_path
):
return
None
from_mgr
=
image_list_manager
.
ImageListManager
()
to_mgr
=
image_list_manager
.
ImageListManager
(
file_path
=
to_image_list_path
)
from_mgr
.
dirName
=
from_dir
sub_dir_list
=
os
.
listdir
(
from_dir
)
for
sub_dir
in
sub_dir_list
:
real_sub_dir
=
os
.
path
.
join
(
from_dir
,
sub_dir
)
if
not
os
.
path
.
isdir
(
real_sub_dir
):
continue
img_list
=
os
.
listdir
(
real_sub_dir
)
img_path
=
[]
for
img
in
img_list
:
real_img
=
os
.
path
.
join
(
real_sub_dir
,
img
)
if
not
os
.
path
.
isfile
(
real_img
):
continue
img_path
.
append
(
"{}/{}"
.
format
(
sub_dir
,
img
))
if
len
(
img_path
)
==
0
:
continue
from_mgr
.
addClassify
(
sub_dir
)
from_mgr
.
resetImageList
(
sub_dir
,
img_path
)
return
oneKeyImport
(
from_mgr
=
from_mgr
,
to_mgr
=
to_mgr
)
def
oneKeyImport
(
from_mgr
:
image_list_manager
.
ImageListManager
,
to_mgr
:
image_list_manager
.
ImageListManager
):
"""一键导入"""
count
=
0
for
classify
in
from_mgr
.
classifyList
:
img_list
=
from_mgr
.
realPathList
(
classify
)
to_mgr
.
addClassify
(
classify
)
to_img_list
=
to_mgr
.
imageList
(
classify
)
new_img_list
=
[]
for
img
in
img_list
:
from_image_path
=
img
to_dir_path
=
os
.
path
.
join
(
to_mgr
.
dirName
,
"images"
)
md5
=
fileMD5
(
from_image_path
)
file_ext
=
fileExtension
(
from_image_path
)
new_path
=
os
.
path
.
join
(
to_dir_path
,
md5
+
file_ext
)
if
os
.
path
.
exists
(
new_path
):
# 如果新文件 MD5 重复跳过后面的复制文件操作
continue
copyFile
(
from_image_path
,
new_path
)
new_img_list
.
append
(
"images/"
+
md5
+
file_ext
)
count
+=
1
to_img_list
+=
new_img_list
to_mgr
.
resetImageList
(
classify
,
to_img_list
)
to_mgr
.
writeFile
()
return
count
def
newFile
(
file_path
:
str
):
"""创建文件"""
if
os
.
path
.
exists
(
file_path
):
return
False
else
:
with
open
(
file_path
,
'w'
)
as
f
:
pass
return
True
def
isEmptyDir
(
dir_path
:
str
):
"""判断目录是否为空"""
return
not
os
.
listdir
(
dir_path
)
def
initLibrary
(
dir_path
:
str
):
"""初始化库"""
images_dir
=
os
.
path
.
join
(
dir_path
,
"images"
)
if
not
os
.
path
.
exists
(
images_dir
):
os
.
makedirs
(
images_dir
)
image_list_path
=
os
.
path
.
join
(
dir_path
,
"image_list.txt"
)
newFile
(
image_list_path
)
return
os
.
path
.
exists
(
dir_path
)
deploy/shitu_index_manager/resource/add_classify.png
0 → 100644
浏览文件 @
f64bec7f
3.8 KB
deploy/shitu_index_manager/resource/add_image.png
0 → 100644
浏览文件 @
f64bec7f
2.0 KB
deploy/shitu_index_manager/resource/app_icon.png
0 → 100644
浏览文件 @
f64bec7f
23.6 KB
deploy/shitu_index_manager/resource/app_menu.png
0 → 100644
浏览文件 @
f64bec7f
1.9 KB
deploy/shitu_index_manager/resource/remove_classify.png
0 → 100644
浏览文件 @
f64bec7f
3.5 KB
deploy/shitu_index_manager/resource/remove_image.png
0 → 100644
浏览文件 @
f64bec7f
1.5 KB
deploy/shitu_index_manager/resource/save_image_Library.png
0 → 100644
浏览文件 @
f64bec7f
2.2 KB
deploy/shitu_index_manager/resource/search_classify.png
0 → 100644
浏览文件 @
f64bec7f
3.1 KB
deploy/shitu_index_manager/ui/AddClassifyDialog.ui
0 → 100644
浏览文件 @
f64bec7f
<?xml version="1.0" encoding="UTF-8"?>
<ui
version=
"4.0"
>
<class>
AddClassifyDialog
</class>
<widget
class=
"QDialog"
name=
"AddClassifyDialog"
>
<property
name=
"geometry"
>
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
286
</width>
<height>
127
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
<string>
添加分类
</string>
</property>
<property
name=
"modal"
>
<bool>
true
</bool>
</property>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout"
>
<item>
<widget
class=
"QLabel"
name=
"label"
>
<property
name=
"text"
>
<string>
分类名称
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QLineEdit"
name=
"lineEdit"
/>
</item>
<item>
<spacer
name=
"verticalSpacer"
>
<property
name=
"orientation"
>
<enum>
Qt::Vertical
</enum>
</property>
<property
name=
"sizeHint"
stdset=
"0"
>
<size>
<width>
20
</width>
<height>
11
</height>
</size>
</property>
</spacer>
</item>
<item>
<widget
class=
"QDialogButtonBox"
name=
"buttonBox"
>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"standardButtons"
>
<set>
QDialogButtonBox::Cancel|QDialogButtonBox::Ok
</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>
buttonBox
</sender>
<signal>
accepted()
</signal>
<receiver>
AddClassifyDialog
</receiver>
<slot>
accept()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
248
</x>
<y>
254
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
157
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
<connection>
<sender>
buttonBox
</sender>
<signal>
rejected()
</signal>
<receiver>
AddClassifyDialog
</receiver>
<slot>
reject()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
316
</x>
<y>
260
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
286
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
</connections>
</ui>
deploy/shitu_index_manager/ui/ImageEditClassifyDialog.ui
0 → 100644
浏览文件 @
f64bec7f
<?xml version="1.0" encoding="UTF-8"?>
<ui
version=
"4.0"
>
<class>
Dialog
</class>
<widget
class=
"QDialog"
name=
"Dialog"
>
<property
name=
"geometry"
>
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
414
</width>
<height>
415
</height>
</rect>
</property>
<property
name=
"minimumSize"
>
<size>
<width>
0
</width>
<height>
0
</height>
</size>
</property>
<property
name=
"windowTitle"
>
<string>
编辑图像分类
</string>
</property>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout"
>
<item>
<widget
class=
"QLabel"
name=
"label"
>
<property
name=
"text"
>
<string>
原分类
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QLineEdit"
name=
"oldLineEdit"
>
<property
name=
"enabled"
>
<bool>
false
</bool>
</property>
</widget>
</item>
<item>
<widget
class=
"QLabel"
name=
"label_2"
>
<property
name=
"text"
>
<string>
新分类
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QLineEdit"
name=
"newLineEdit"
>
<property
name=
"enabled"
>
<bool>
false
</bool>
</property>
</widget>
</item>
<item>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout"
>
<item>
<widget
class=
"QLineEdit"
name=
"searchWordLineEdit"
/>
</item>
<item>
<widget
class=
"QPushButton"
name=
"searchButton"
>
<property
name=
"text"
>
<string>
查找
</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget
class=
"QListView"
name=
"classifyListView"
>
<property
name=
"enabled"
>
<bool>
true
</bool>
</property>
<property
name=
"minimumSize"
>
<size>
<width>
400
</width>
<height>
200
</height>
</size>
</property>
</widget>
</item>
<item>
<widget
class=
"QDialogButtonBox"
name=
"buttonBox"
>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"standardButtons"
>
<set>
QDialogButtonBox::Cancel|QDialogButtonBox::Ok
</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>
buttonBox
</sender>
<signal>
accepted()
</signal>
<receiver>
Dialog
</receiver>
<slot>
accept()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
248
</x>
<y>
254
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
157
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
<connection>
<sender>
buttonBox
</sender>
<signal>
rejected()
</signal>
<receiver>
Dialog
</receiver>
<slot>
reject()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
316
</x>
<y>
260
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
286
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
</connections>
</ui>
deploy/shitu_index_manager/ui/MainWindow.ui
0 → 100644
浏览文件 @
f64bec7f
<?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>
833
</width>
<height>
538
</height>
</rect>
</property>
<property
name=
"minimumSize"
>
<size>
<width>
0
</width>
<height>
0
</height>
</size>
</property>
<property
name=
"windowTitle"
>
<string>
识图图像库管理
</string>
</property>
<widget
class=
"QWidget"
name=
"centralwidget"
>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout_3"
>
<item>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_3"
>
<item>
<widget
class=
"QToolButton"
name=
"appMenuBtn"
>
<property
name=
"text"
>
<string>
...
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QToolButton"
name=
"saveImageLibraryBtn"
>
<property
name=
"text"
>
<string>
...
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QToolButton"
name=
"addClassifyBtn"
>
<property
name=
"text"
>
<string>
...
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QToolButton"
name=
"removeClassifyBtn"
>
<property
name=
"text"
>
<string>
...
</string>
</property>
</widget>
</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=
"QSlider"
name=
"imageScaleSlider"
>
<property
name=
"maximumSize"
>
<size>
<width>
400
</width>
<height>
16777215
</height>
</size>
</property>
<property
name=
"minimum"
>
<number>
1
</number>
</property>
<property
name=
"maximum"
>
<number>
8
</number>
</property>
<property
name=
"pageStep"
>
<number>
2
</number>
</property>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget
class=
"QSplitter"
name=
"splitter"
>
<property
name=
"sizePolicy"
>
<sizepolicy
hsizetype=
"Expanding"
vsizetype=
"Expanding"
>
<horstretch>
0
</horstretch>
<verstretch>
0
</verstretch>
</sizepolicy>
</property>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<widget
class=
"QWidget"
name=
""
>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout_2"
>
<item>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout"
>
<item>
<widget
class=
"QComboBox"
name=
"searchClassifyHistoryCmb"
>
<property
name=
"sizePolicy"
>
<sizepolicy
hsizetype=
"Expanding"
vsizetype=
"Fixed"
>
<horstretch>
0
</horstretch>
<verstretch>
0
</verstretch>
</sizepolicy>
</property>
<property
name=
"editable"
>
<bool>
true
</bool>
</property>
</widget>
</item>
<item>
<widget
class=
"QToolButton"
name=
"searchClassifyBtn"
>
<property
name=
"text"
>
<string>
...
</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget
class=
"QListView"
name=
"classifyListView"
>
<property
name=
"sizePolicy"
>
<sizepolicy
hsizetype=
"Expanding"
vsizetype=
"Expanding"
>
<horstretch>
0
</horstretch>
<verstretch>
0
</verstretch>
</sizepolicy>
</property>
<property
name=
"minimumSize"
>
<size>
<width>
200
</width>
<height>
0
</height>
</size>
</property>
<property
name=
"editTriggers"
>
<set>
QAbstractItemView::NoEditTriggers
</set>
</property>
</widget>
</item>
</layout>
</widget>
<widget
class=
"QWidget"
name=
""
>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout"
>
<item>
<layout
class=
"QHBoxLayout"
name=
"horizontalLayout_2"
>
<item>
<widget
class=
"QToolButton"
name=
"addImageBtn"
>
<property
name=
"text"
>
<string>
...
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QToolButton"
name=
"removeImageBtn"
>
<property
name=
"text"
>
<string>
...
</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>
<widget
class=
"QListWidget"
name=
"imageListWidget"
>
<property
name=
"sizePolicy"
>
<sizepolicy
hsizetype=
"Expanding"
vsizetype=
"Expanding"
>
<horstretch>
0
</horstretch>
<verstretch>
0
</verstretch>
</sizepolicy>
</property>
<property
name=
"minimumSize"
>
<size>
<width>
200
</width>
<height>
0
</height>
</size>
</property>
<property
name=
"styleSheet"
>
<string
notr=
"true"
>
QListWidget::Item:hover{background:skyblue;padding-top:0px; padding-bottom:0px;}
QListWidget::item:selected{background:rgb(245, 121, 0); color:red;}
</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget
class=
"QStatusBar"
name=
"statusbar"
/>
</widget>
<resources/>
<connections/>
</ui>
deploy/shitu_index_manager/ui/NewlibraryDialog.ui
0 → 100644
浏览文件 @
f64bec7f
<?xml version="1.0" encoding="UTF-8"?>
<ui
version=
"4.0"
>
<class>
NewlibraryDialog
</class>
<widget
class=
"QDialog"
name=
"NewlibraryDialog"
>
<property
name=
"geometry"
>
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
414
</width>
<height>
230
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
<string>
新建/重建 索引
</string>
</property>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout"
>
<item>
<widget
class=
"QLabel"
name=
"label"
>
<property
name=
"text"
>
<string>
索引方式
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QComboBox"
name=
"indexMethodCmb"
>
<property
name=
"enabled"
>
<bool>
true
</bool>
</property>
<property
name=
"currentIndex"
>
<number>
0
</number>
</property>
<item>
<property
name=
"text"
>
<string>
HNSW32
</string>
</property>
</item>
<item>
<property
name=
"text"
>
<string>
FLAT
</string>
</property>
</item>
<item>
<property
name=
"text"
>
<string>
IVF
</string>
</property>
</item>
</widget>
</item>
<item>
<widget
class=
"QCheckBox"
name=
"resetCheckBox"
>
<property
name=
"text"
>
<string>
重建索引,警告:会覆盖原索引
</string>
</property>
</widget>
</item>
<item>
<spacer
name=
"verticalSpacer"
>
<property
name=
"orientation"
>
<enum>
Qt::Vertical
</enum>
</property>
<property
name=
"sizeHint"
stdset=
"0"
>
<size>
<width>
20
</width>
<height>
80
</height>
</size>
</property>
</spacer>
</item>
<item>
<widget
class=
"QDialogButtonBox"
name=
"buttonBox"
>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"standardButtons"
>
<set>
QDialogButtonBox::Cancel|QDialogButtonBox::Ok
</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>
buttonBox
</sender>
<signal>
accepted()
</signal>
<receiver>
NewlibraryDialog
</receiver>
<slot>
accept()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
248
</x>
<y>
254
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
157
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
<connection>
<sender>
buttonBox
</sender>
<signal>
rejected()
</signal>
<receiver>
NewlibraryDialog
</receiver>
<slot>
reject()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
316
</x>
<y>
260
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
286
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
</connections>
</ui>
deploy/shitu_index_manager/ui/RenameClassifyDialog.ui
0 → 100644
浏览文件 @
f64bec7f
<?xml version="1.0" encoding="UTF-8"?>
<ui
version=
"4.0"
>
<class>
RenameClassifyDialog
</class>
<widget
class=
"QDialog"
name=
"RenameClassifyDialog"
>
<property
name=
"geometry"
>
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
342
</width>
<height>
194
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
<string>
重命名分类
</string>
</property>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout"
>
<item>
<widget
class=
"QLabel"
name=
"oldlabel"
>
<property
name=
"text"
>
<string>
原名称
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QLineEdit"
name=
"oldNameLineEdit"
>
<property
name=
"enabled"
>
<bool>
false
</bool>
</property>
</widget>
</item>
<item>
<widget
class=
"QLabel"
name=
"newlabel"
>
<property
name=
"text"
>
<string>
新名称
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QLineEdit"
name=
"newNameLineEdit"
/>
</item>
<item>
<spacer
name=
"verticalSpacer"
>
<property
name=
"orientation"
>
<enum>
Qt::Vertical
</enum>
</property>
<property
name=
"sizeHint"
stdset=
"0"
>
<size>
<width>
20
</width>
<height>
14
</height>
</size>
</property>
</spacer>
</item>
<item>
<widget
class=
"QDialogButtonBox"
name=
"buttonBox"
>
<property
name=
"orientation"
>
<enum>
Qt::Horizontal
</enum>
</property>
<property
name=
"standardButtons"
>
<set>
QDialogButtonBox::Cancel|QDialogButtonBox::Ok
</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>
buttonBox
</sender>
<signal>
accepted()
</signal>
<receiver>
RenameClassifyDialog
</receiver>
<slot>
accept()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
248
</x>
<y>
254
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
157
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
<connection>
<sender>
buttonBox
</sender>
<signal>
rejected()
</signal>
<receiver>
RenameClassifyDialog
</receiver>
<slot>
reject()
</slot>
<hints>
<hint
type=
"sourcelabel"
>
<x>
316
</x>
<y>
260
</y>
</hint>
<hint
type=
"destinationlabel"
>
<x>
286
</x>
<y>
274
</y>
</hint>
</hints>
</connection>
</connections>
</ui>
deploy/shitu_index_manager/ui/WaitDialog.ui
0 → 100644
浏览文件 @
f64bec7f
<?xml version="1.0" encoding="UTF-8"?>
<ui
version=
"4.0"
>
<class>
WaitDialog
</class>
<widget
class=
"QDialog"
name=
"WaitDialog"
>
<property
name=
"windowModality"
>
<enum>
Qt::NonModal
</enum>
</property>
<property
name=
"geometry"
>
<rect>
<x>
0
</x>
<y>
0
</y>
<width>
324
</width>
<height>
78
</height>
</rect>
</property>
<property
name=
"windowTitle"
>
<string>
请等待
</string>
</property>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout"
>
<item>
<widget
class=
"QLabel"
name=
"msgLabel"
>
<property
name=
"text"
>
<string>
正在更新索引库,请等待。。。
</string>
</property>
</widget>
</item>
<item>
<widget
class=
"QProgressBar"
name=
"progressBar"
>
<property
name=
"maximum"
>
<number>
0
</number>
</property>
<property
name=
"value"
>
<number>
-1
</number>
</property>
</widget>
</item>
<item>
<spacer
name=
"verticalSpacer"
>
<property
name=
"orientation"
>
<enum>
Qt::Vertical
</enum>
</property>
<property
name=
"sizeHint"
stdset=
"0"
>
<size>
<width>
20
</width>
<height>
1
</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录