Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 75 additions & 2 deletions PPOCRLabel.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
QColor,
QIcon,
QFontDatabase,
QFontMetrics,
)
from PyQt5.QtWidgets import (
QMainWindow,
Expand Down Expand Up @@ -98,6 +99,7 @@
SETTING_WIN_POSE,
SETTING_WIN_SIZE,
SETTING_WIN_STATE,
SETTING_FONT_SIZE,
)
from libs.utils import (
addActions,
Expand Down Expand Up @@ -297,6 +299,9 @@ def get_str(str_id):
self.fileDock = QDockWidget(self.fileListName, self)
self.fileDock.setObjectName(get_str("files"))
self.fileDock.setWidget(fileListContainer)
dock_font = self.fileDock.font()
dock_font.setPointSize(20)
self.fileDock.setFont(dock_font)
self.addDockWidget(Qt.LeftDockWidgetArea, self.fileDock)

# ================== Key List ==================
Expand Down Expand Up @@ -372,6 +377,7 @@ def get_str(str_id):

# Create and add a widget for showing current label item index
self.indexList = QListWidget()
self.indexList.setSpacing(0)
self.indexList.setMaximumSize(30, 16777215) # limit max width
self.indexList.setEditTriggers(QAbstractItemView.NoEditTriggers) # no editable
self.indexList.itemSelectionChanged.connect(self.indexSelectionChanged)
Expand All @@ -387,6 +393,7 @@ def get_str(str_id):

# Create and add a widget for showing current label items
self.labelList = EditInList()
self.labelList.setSpacing(0)
labelListContainer = QWidget()
labelListContainer.setLayout(listLayout)
self.labelList.itemSelectionChanged.connect(self.labelSelectionChanged)
Expand Down Expand Up @@ -924,6 +931,15 @@ def get_str(str_id):
enabled=True,
)

settings_action = action(
get_str("settings"),
self.showSettingsDialog,
None,
"help",
get_str("settingsDetail"),
enabled=True,
)

self.editButton.setDefaultAction(edit)
self.newButton.setDefaultAction(create)
self.createpolyButton.setDefaultAction(createpoly)
Expand Down Expand Up @@ -1154,6 +1170,7 @@ def get_str(str_id):
self.autoReRecognitionOption,
self.autoSaveUnsavedChangesOption,
None,
settings_action,
resetAll,
deleteImg,
quit,
Expand Down Expand Up @@ -1276,6 +1293,9 @@ def get_str(str_id):
# selected shape color
self.selected_shape_color = selected_shape_color

# apply font size
self.applyFontSize(self.settings.get(SETTING_FONT_SIZE, 12))

def menu(self, title, actions=None):
menu = self.menuBar().addMenu(title)
if actions:
Expand Down Expand Up @@ -1398,6 +1418,58 @@ def showKeysDialog(self):
msg = keysInfo(self.lang)
QMessageBox.information(self, "Information", msg)

def applyFontSize(self, fontSize):
# 1. Update standard font objects
f = self.font()
f.setPointSize(fontSize)
QApplication.instance().setFont(f)
self.setFont(f)

# 2. Universal Stylesheet with explicit component targeting.
# This is more effective on macOS than a generic QWidget rule.
style = f"""
QWidget, QLabel, QDockWidget, QMenuBar, QMenu, QStatusBar, QListWidget, QSpinBox, QToolButton {{
font-size: {fontSize}pt;
}}
QDockWidget {{
font-size: {fontSize}pt;
font-weight: bold;
}}
QDockWidget::title {{
font-size: {fontSize}pt;
padding: 4px;
}}
"""
QApplication.instance().setStyleSheet(style)

# 3. Update specific measurements
fm = QFontMetrics(f)
if hasattr(self, "indexList"):
width = fm.width("8888") + 10
self.indexList.setFixedWidth(width)
self.indexList.setUniformItemSizes(True)
if hasattr(self, "labelList"):
self.labelList.setUniformItemSizes(True)
if hasattr(self, "AutoRecognitionNum"):
width = fm.width("8888") + 30
self.AutoRecognitionNum.setFixedWidth(width)

def showSettingsDialog(self):
from PyQt5.QtWidgets import QInputDialog

fontSize, ok = QInputDialog.getInt(
self,
self.stringBundle.getString("settings"),
self.stringBundle.getString("fontSize"),
self.settings.get(SETTING_FONT_SIZE, 12),
6,
100,
)
if ok:
self.settings[SETTING_FONT_SIZE] = fontSize
self.settings.save()
self.applyFontSize(fontSize)

def createShape(self):
assert self.beginner()
self.canvas.setEditing(False)
Expand Down Expand Up @@ -1759,8 +1831,9 @@ def addLabel(self, shape):
self.shapesToItems[shape] = item
# add current label item index before label string
current_index = QListWidgetItem(str(self.labelList.count()))
current_index.setTextAlignment(Qt.AlignHCenter)
current_index.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
self.indexList.addItem(current_index)
item.setTextAlignment(Qt.AlignVCenter)
self.labelList.addItem(item)
# print('item in add label is ',[(p.x(), p.y()) for p in shape.points], shape.label)

Expand Down Expand Up @@ -1862,7 +1935,7 @@ def updateIndexList(self):
self.indexList.clear()
for i in range(self.labelList.count()):
string = QListWidgetItem(str(i))
string.setTextAlignment(Qt.AlignHCenter)
string.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
self.indexList.addItem(string)

def saveLabels(self, annotationFilePath, mode="Auto"):
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ PPOCRLabelv3 is a semi-automatic graphic annotation tool suitable for OCR field,
| <img src="./data/gif/multi-point.gif" width="80%"/> | <img src="./data/gif/kie.gif" width="100%"/> |

### Recent Update
- 2026.03:
- Add the `Settings` to change the application's font size.
- 2025.06:
- Add the `Resort Bounding Box Positions` features. For usage details, please refer to the `11. Additional Feature Description` in the `2.1 Operational Steps` section below.
- 2024.11:
Expand Down Expand Up @@ -184,6 +186,7 @@ PPOCRLabel.exe --lang ch
- `v`: After pressing, the up, down, left, and right arrow keys will move the 4th vertex individually.
- `b`: After pressing, the up, down, left, and right arrow keys will revert to the default action of moving the entire bounding box.
- `Bottom right` -> `Resort Positions`: Clicking this will arrange the bounding boxes in order from top to bottom and left to right. This is used to address the issue of manually adjusting the order after adding rectangular labels when identifying table structures.
- `File` -> `Settings`: Clicking this will open a popup where the user can set the application's font size. This setting is saved and applied to all UI elements in future sessions.

### 2.2 Table Annotation

Expand Down
3 changes: 3 additions & 0 deletions README_ch.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ PPOCRLabelv3是一款适用于OCR领域的半自动化图形标注工具,内
| <img src="./data/gif/multi-point.gif" width="80%"/> | <img src="./data/gif/kie.gif" width="100%"/> |

#### 近期更新
- 2026.03:
- 在`文件`菜单下新增`设置`功能,用于修改应用程序的字体大小。
- 2025.06:
- 新增`重新排序坐标框位置`功能,使用方法详见下方`2.1 操作步骤`的`11. 补充功能说明`。
- 2024.11:
Expand Down Expand Up @@ -167,6 +169,7 @@ PPOCRLabel.exe --lang ch
- `v` :按下后,此时使用键盘的上下左右按键将单独移动第4个顶点
- `b` :按下后,此时使用键盘的上下左右按键将恢复默认的整体移动整个标记框
- `右下方` -> `重新排序位置` : 点击后会将标注框按照从上到下、从左到右的顺序进行排列。用于解决表格结构标识时,需要手动补充矩形标识后的顺序调整问题。
- `文件` -> `设置` :点击后弹出窗口,用户可以设置应用程序的字体大小。该设置将被保存并在未来的会话中应用于所有UI元素。

### 2.2 表格标注([视频演示](https://www.bilibili.com/video/BV1wR4y1v7JE/?share_source=copy_web&vd_source=cf1f9d24648d49636e3d109c9f9a377d&t=1998))

Expand Down
1 change: 1 addition & 0 deletions libs/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@
FORMAT_YOLO = "YOLO"
SETTING_DRAW_SQUARE = "draw/square"
SETTING_LABEL_FILE_FORMAT = "labelFileFormat"
SETTING_FONT_SIZE = "fontsize"
DEFAULT_ENCODING = "utf-8"
82 changes: 46 additions & 36 deletions libs/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -9092,7 +9092,7 @@
\xc2\xbe\x6b\xc0\x55\xc8\x31\xa0\x80\x1e\x20\x21\xee\xf8\x2f\xe5\
\xea\x8d\x7f\x05\xf8\x03\xd8\xcb\xf0\xd4\x8e\x80\x5e\x37\x00\x00\
\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
\x00\x00\x0e\x49\
\x00\x00\x0e\x91\
\x73\
\x61\x76\x65\x41\x73\x44\x65\x74\x61\x69\x6c\x3d\xe5\xb0\x87\xe6\
\xa0\x87\xe7\xad\xbe\xe4\xbf\x9d\xe5\xad\x98\xe5\x88\xb0\xe5\x85\
Expand Down Expand Up @@ -9322,7 +9322,12 @@
\x8f\xe4\xbd\x8d\xe7\xbd\xae\x0a\x72\x65\x73\x6f\x72\x74\x70\x6f\
\x73\x69\x74\x69\x6f\x6e\x64\x65\x74\x61\x69\x6c\x3d\xe9\x87\x8d\
\xe6\x96\xb0\xe6\x8e\x92\xe5\xba\x8f\xe5\x9d\x90\xe6\xa0\x87\xe6\
\xa1\x86\xe4\xbd\x8d\xe7\xbd\xae\
\xa1\x86\xe4\xbd\x8d\xe7\xbd\xae\x0a\x73\x65\x74\x74\x69\x6e\x67\
\x73\x3d\xe8\xae\xbe\xe7\xbd\xae\x0a\x73\x65\x74\x74\x69\x6e\x67\
\x73\x44\x65\x74\x61\x69\x6c\x3d\xe5\xba\x94\xe7\x94\xa8\xe7\xa8\
\x8b\xe5\xba\x8f\xe8\xae\xbe\xe7\xbd\xae\x0a\x66\x6f\x6e\x74\x53\
\x69\x7a\x65\x3d\xe5\xad\x97\xe4\xbd\x93\xe5\xa4\xa7\xe5\xb0\x8f\
\
\x00\x00\x03\x12\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
Expand Down Expand Up @@ -11012,7 +11017,7 @@
\xbe\xde\xa3\x73\x07\x05\x00\x88\x83\x48\x18\x92\xaf\x02\xff\x03\
\x39\x5c\xc9\x23\xd1\xf6\x50\x87\x00\x00\x00\x00\x49\x45\x4e\x44\
\xae\x42\x60\x82\
\x00\x00\x0e\x40\
\x00\x00\x0e\x89\
\x6f\
\x70\x65\x6e\x46\x69\x6c\x65\x3d\x4f\x70\x65\x6e\x0a\x6f\x70\x65\
\x6e\x46\x69\x6c\x65\x44\x65\x74\x61\x69\x6c\x3d\x4f\x70\x65\x6e\
Expand Down Expand Up @@ -11241,7 +11246,12 @@
\x70\x6f\x73\x69\x74\x69\x6f\x6e\x0a\x72\x65\x73\x6f\x72\x74\x70\
\x6f\x73\x69\x74\x69\x6f\x6e\x64\x65\x74\x61\x69\x6c\x3d\x52\x65\
\x73\x6f\x72\x74\x20\x74\x68\x65\x20\x62\x6f\x75\x6e\x64\x69\x6e\
\x67\x20\x62\x6f\x78\x20\x70\x6f\x73\x69\x74\x69\x6f\x6e\x73\
\x67\x20\x62\x6f\x78\x20\x70\x6f\x73\x69\x74\x69\x6f\x6e\x73\x0a\
\x73\x65\x74\x74\x69\x6e\x67\x73\x3d\x53\x65\x74\x74\x69\x6e\x67\
\x73\x0a\x73\x65\x74\x74\x69\x6e\x67\x73\x44\x65\x74\x61\x69\x6c\
\x3d\x41\x70\x70\x6c\x69\x63\x61\x74\x69\x6f\x6e\x20\x73\x65\x74\
\x74\x69\x6e\x67\x73\x0a\x66\x6f\x6e\x74\x53\x69\x7a\x65\x3d\x46\
\x6f\x6e\x74\x20\x53\x69\x7a\x65\
\x00\x00\x0e\x35\
\x89\
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
Expand Down Expand Up @@ -11644,21 +11654,21 @@
\x00\x00\x00\xfc\x00\x00\x00\x00\x00\x01\x00\x02\x2b\xd3\
\x00\x00\x01\x0c\x00\x00\x00\x00\x00\x01\x00\x02\x30\x8c\
\x00\x00\x01\x20\x00\x00\x00\x00\x00\x01\x00\x02\x34\xdb\
\x00\x00\x01\x40\x00\x00\x00\x00\x00\x01\x00\x02\x43\x28\
\x00\x00\x01\x5a\x00\x00\x00\x00\x00\x01\x00\x02\x46\x3e\
\x00\x00\x01\x74\x00\x00\x00\x00\x00\x01\x00\x02\x4a\x90\
\x00\x00\x01\x8a\x00\x00\x00\x00\x00\x01\x00\x02\x4e\xc6\
\x00\x00\x01\xa4\x00\x00\x00\x00\x00\x01\x00\x02\x58\x0a\
\x00\x00\x01\xb6\x00\x00\x00\x00\x00\x01\x00\x02\x60\x66\
\x00\x00\x01\xc8\x00\x00\x00\x00\x00\x01\x00\x02\x61\xb9\
\x00\x00\x01\xda\x00\x00\x00\x00\x00\x01\x00\x02\x6b\x0a\
\x00\x00\x01\xf2\x00\x00\x00\x00\x00\x01\x00\x02\x70\x63\
\x00\x00\x02\x04\x00\x00\x00\x00\x00\x01\x00\x02\x7c\x48\
\x00\x00\x02\x20\x00\x00\x00\x00\x00\x01\x00\x02\x7e\xef\
\x00\x00\x02\x3a\x00\x00\x00\x00\x00\x01\x00\x02\x8f\x6b\
\x00\x00\x02\x4e\x00\x00\x00\x00\x00\x01\x00\x02\x9a\x6a\
\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x02\xaa\xe3\
\x00\x00\x02\x7e\x00\x00\x00\x00\x00\x01\x00\x02\xb9\x27\
\x00\x00\x01\x40\x00\x00\x00\x00\x00\x01\x00\x02\x43\x70\
\x00\x00\x01\x5a\x00\x00\x00\x00\x00\x01\x00\x02\x46\x86\
\x00\x00\x01\x74\x00\x00\x00\x00\x00\x01\x00\x02\x4a\xd8\
\x00\x00\x01\x8a\x00\x00\x00\x00\x00\x01\x00\x02\x4f\x0e\
\x00\x00\x01\xa4\x00\x00\x00\x00\x00\x01\x00\x02\x58\x52\
\x00\x00\x01\xb6\x00\x00\x00\x00\x00\x01\x00\x02\x60\xae\
\x00\x00\x01\xc8\x00\x00\x00\x00\x00\x01\x00\x02\x62\x01\
\x00\x00\x01\xda\x00\x00\x00\x00\x00\x01\x00\x02\x6b\x52\
\x00\x00\x01\xf2\x00\x00\x00\x00\x00\x01\x00\x02\x70\xab\
\x00\x00\x02\x04\x00\x00\x00\x00\x00\x01\x00\x02\x7c\x90\
\x00\x00\x02\x20\x00\x00\x00\x00\x00\x01\x00\x02\x7f\x37\
\x00\x00\x02\x3a\x00\x00\x00\x00\x00\x01\x00\x02\x8f\xb3\
\x00\x00\x02\x4e\x00\x00\x00\x00\x00\x01\x00\x02\x9a\xb2\
\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x02\xab\x2b\
\x00\x00\x02\x7e\x00\x00\x00\x00\x00\x01\x00\x02\xb9\xb8\
"

qt_resource_struct_v2 = b"\
Expand Down Expand Up @@ -11705,36 +11715,36 @@
\x00\x00\x01\x0c\x00\x00\x00\x00\x00\x01\x00\x02\x30\x8c\
\x00\x00\x01\x9c\xc0\x4e\x25\x94\
\x00\x00\x01\x20\x00\x00\x00\x00\x00\x01\x00\x02\x34\xdb\
\x00\x00\x01\x9d\x16\xc0\x3a\x2f\
\x00\x00\x01\x40\x00\x00\x00\x00\x00\x01\x00\x02\x43\x28\
\x00\x00\x01\x9d\x27\x67\x29\xa7\
\x00\x00\x01\x40\x00\x00\x00\x00\x00\x01\x00\x02\x43\x70\
\x00\x00\x01\x9c\xc0\x4e\x25\x92\
\x00\x00\x01\x5a\x00\x00\x00\x00\x00\x01\x00\x02\x46\x3e\
\x00\x00\x01\x5a\x00\x00\x00\x00\x00\x01\x00\x02\x46\x86\
\x00\x00\x01\x9c\xc0\x4e\x25\x91\
\x00\x00\x01\x74\x00\x00\x00\x00\x00\x01\x00\x02\x4a\x90\
\x00\x00\x01\x74\x00\x00\x00\x00\x00\x01\x00\x02\x4a\xd8\
\x00\x00\x01\x9c\xc0\x4e\x25\x94\
\x00\x00\x01\x8a\x00\x00\x00\x00\x00\x01\x00\x02\x4e\xc6\
\x00\x00\x01\x8a\x00\x00\x00\x00\x00\x01\x00\x02\x4f\x0e\
\x00\x00\x01\x9c\xc0\x4e\x25\x90\
\x00\x00\x01\xa4\x00\x00\x00\x00\x00\x01\x00\x02\x58\x0a\
\x00\x00\x01\xa4\x00\x00\x00\x00\x00\x01\x00\x02\x58\x52\
\x00\x00\x01\x9c\xc0\x4e\x25\x90\
\x00\x00\x01\xb6\x00\x00\x00\x00\x00\x01\x00\x02\x60\x66\
\x00\x00\x01\xb6\x00\x00\x00\x00\x00\x01\x00\x02\x60\xae\
\x00\x00\x01\x9c\xc0\x4e\x25\x91\
\x00\x00\x01\xc8\x00\x00\x00\x00\x00\x01\x00\x02\x61\xb9\
\x00\x00\x01\xc8\x00\x00\x00\x00\x00\x01\x00\x02\x62\x01\
\x00\x00\x01\x9c\xc0\x4e\x25\x92\
\x00\x00\x01\xda\x00\x00\x00\x00\x00\x01\x00\x02\x6b\x0a\
\x00\x00\x01\xda\x00\x00\x00\x00\x00\x01\x00\x02\x6b\x52\
\x00\x00\x01\x9c\xc0\x4e\x25\x91\
\x00\x00\x01\xf2\x00\x00\x00\x00\x00\x01\x00\x02\x70\x63\
\x00\x00\x01\xf2\x00\x00\x00\x00\x00\x01\x00\x02\x70\xab\
\x00\x00\x01\x9c\xc0\x4e\x25\x94\
\x00\x00\x02\x04\x00\x00\x00\x00\x00\x01\x00\x02\x7c\x48\
\x00\x00\x02\x04\x00\x00\x00\x00\x00\x01\x00\x02\x7c\x90\
\x00\x00\x01\x9c\xc0\x4e\x25\x92\
\x00\x00\x02\x20\x00\x00\x00\x00\x00\x01\x00\x02\x7e\xef\
\x00\x00\x02\x20\x00\x00\x00\x00\x00\x01\x00\x02\x7f\x37\
\x00\x00\x01\x9c\xc0\x4e\x25\x93\
\x00\x00\x02\x3a\x00\x00\x00\x00\x00\x01\x00\x02\x8f\x6b\
\x00\x00\x02\x3a\x00\x00\x00\x00\x00\x01\x00\x02\x8f\xb3\
\x00\x00\x01\x9c\xc0\x4e\x25\x93\
\x00\x00\x02\x4e\x00\x00\x00\x00\x00\x01\x00\x02\x9a\x6a\
\x00\x00\x02\x4e\x00\x00\x00\x00\x00\x01\x00\x02\x9a\xb2\
\x00\x00\x01\x9c\xc0\x4e\x25\x93\
\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x02\xaa\xe3\
\x00\x00\x01\x9d\x16\xc0\x3a\x2e\
\x00\x00\x02\x7e\x00\x00\x00\x00\x00\x01\x00\x02\xb9\x27\
\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x02\xab\x2b\
\x00\x00\x01\x9d\x27\x67\x05\xcb\
\x00\x00\x02\x7e\x00\x00\x00\x00\x00\x01\x00\x02\xb9\xb8\
\x00\x00\x01\x9c\xc0\x4e\x25\x93\
"

Expand Down
5 changes: 4 additions & 1 deletion resources/strings/strings-en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,7 @@ exportJSON=Export Table Label
expandBox=Expand Box
expandBoxDetail=Expand Box
resortposition=Resort position
resortpositiondetail=Resort the bounding box positions
resortpositiondetail=Resort the bounding box positions
settings=Settings
settingsDetail=Application settings
fontSize=Font Size
5 changes: 4 additions & 1 deletion resources/strings/strings-zh-CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,7 @@ exportJSON=导出表格标注
expandBox=扩大框
expandBoxDetail=扩大所选框
resortposition=重新排序位置
resortpositiondetail=重新排序坐标框位置
resortpositiondetail=重新排序坐标框位置
settings=设置
settingsDetail=应用程序设置
fontSize=字体大小
Loading