Skip to content

Commit

Permalink
Move icons to resource folder, fix the unicode issue, support zh-tw lang
Browse files Browse the repository at this point in the history
  • Loading branch information
tzutalin committed Dec 1, 2018
1 parent 13a700a commit eaac031
Show file tree
Hide file tree
Showing 55 changed files with 371 additions and 125 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
icons/.DS_Store
resources/icons/.DS_Store

resources.py

Expand Down
173 changes: 82 additions & 91 deletions labelImg.py

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions libs/hashableQListWidgetItem.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
try:
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
except ImportError:
# needed for py3+qt4
# Ref:
# http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html
# http://stackoverflow.com/questions/21217399/pyqt4-qtcore-qvariant-object-instead-of-a-string
if sys.version_info.major >= 3:
import sip
sip.setapi('QVariant', 2)
from PyQt4.QtGui import *
from PyQt4.QtCore import *

# PyQt5: TypeError: unhashable type: 'QListWidgetItem'


class HashableQListWidgetItem(QListWidgetItem):

def __init__(self, *args):
super(HashableQListWidgetItem, self).__init__(*args)

def __hash__(self):
return hash(id(self))
2 changes: 1 addition & 1 deletion libs/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def fmtShortcut(text):


def generateColorByText(text):
s = str(ustr(text))
s = ustr(text)
hashCode = int(hashlib.sha256(s.encode('utf-8')).hexdigest(), 16)
r = int((hashCode / 255) % 255)
g = int((hashCode / 65025) % 255)
Expand Down
63 changes: 63 additions & 0 deletions libs/stringBundle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import resources
import os
import sys
from libs.ustr import ustr
try:
from PyQt5.QtCore import *
except ImportError:
if sys.version_info.major >= 3:
import sip
sip.setapi('QVariant', 2)
from PyQt4.QtCore import *


class StringBundle:

__create_key = object()

def __init__(self, create_key, localeStr):
assert(create_key == StringBundle.__create_key), "StringBundle must be created using StringBundle.getBundle"
self.idToMessage = {}
paths = self.__createLookupFallbackList(localeStr)
for path in paths:
self.__loadBundle(path)

@classmethod
def getBundle(cls, localeStr=os.getenv('LANG')):
return StringBundle(cls.__create_key, localeStr)

def getString(self, stringId):
assert(stringId in self.idToMessage), "Missing string id : " + stringId
return self.idToMessage[stringId]

def __createLookupFallbackList(self, localeStr):
resultPaths = []
basePath = ":/strings"
resultPaths.append(basePath)
# Don't follow standard BCP47. Simple fallback
tags = re.split('[^a-zA-Z]', localeStr)
for tag in tags:
lastPath = resultPaths[-1]
resultPaths.append(lastPath + '-' + tag)

return resultPaths

def __loadBundle(self, path):
PROP_SEPERATOR = '='
f = QFile(path)
if f.exists():
if f.open(QIODevice.ReadOnly | QFile.Text):
text = QTextStream(f)
text.setCodec("UTF-8")

while not text.atEnd():
line = ustr(text.readLine())
key_value = line.split(PROP_SEPERATOR)
key = key_value[0].strip()
value = PROP_SEPERATOR.join(key_value[1:]).strip().strip('"')
self.idToMessage[key] = value

f.close()
2 changes: 1 addition & 1 deletion libs/ustr.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def ustr(x):
if type(x) == str:
return x.decode(DEFAULT_ENCODING)
if type(x) == QString:
return unicode(x, DEFAULT_ENCODING)
return unicode(x)
return x
else:
return x
62 changes: 32 additions & 30 deletions resources.qrc
Original file line number Diff line number Diff line change
@@ -1,35 +1,37 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>

<file alias="help">icons/help.png</file>
<file alias="app">icons/app.png</file>
<file alias="expert">icons/expert2.png</file>
<file alias="done">icons/done.png</file>
<file alias="file">icons/file.png</file>
<file alias="labels">icons/labels.png</file>
<file alias="new">icons/objects.png</file>
<file alias="close">icons/close.png</file>
<file alias="fit-width">icons/fit-width.png</file>
<file alias="fit-window">icons/fit-window.png</file>
<file alias="undo">icons/undo.png</file>
<file alias="hide">icons/eye.png</file>
<file alias="quit">icons/quit.png</file>
<file alias="copy">icons/copy.png</file>
<file alias="edit">icons/edit.png</file>
<file alias="open">icons/open.png</file>
<file alias="save">icons/save.png</file>
<file alias="format_voc">icons/format_voc.png</file>
<file alias="format_yolo">icons/format_yolo.png</file>
<file alias="save-as">icons/save-as.png</file>
<file alias="color">icons/color.png</file>
<file alias="color_line">icons/color_line.png</file>
<file alias="zoom">icons/zoom.png</file>
<file alias="zoom-in">icons/zoom-in.png</file>
<file alias="zoom-out">icons/zoom-out.png</file>
<file alias="delete">icons/cancel.png</file>
<file alias="next">icons/next.png</file>
<file alias="prev">icons/prev.png</file>
<file alias="resetall">icons/resetall.png</file>
<file alias="verify">icons/verify.png</file>
<file alias="help">resources/icons/help.png</file>
<file alias="app">resources/icons/app.png</file>
<file alias="expert">resources/icons/expert2.png</file>
<file alias="done">resources/icons/done.png</file>
<file alias="file">resources/icons/file.png</file>
<file alias="labels">resources/icons/labels.png</file>
<file alias="new">resources/icons/objects.png</file>
<file alias="close">resources/icons/close.png</file>
<file alias="fit-width">resources/icons/fit-width.png</file>
<file alias="fit-window">resources/icons/fit-window.png</file>
<file alias="undo">resources/icons/undo.png</file>
<file alias="hide">resources/icons/eye.png</file>
<file alias="quit">resources/icons/quit.png</file>
<file alias="copy">resources/icons/copy.png</file>
<file alias="edit">resources/icons/edit.png</file>
<file alias="open">resources/icons/open.png</file>
<file alias="save">resources/icons/save.png</file>
<file alias="format_voc">resources/icons/format_voc.png</file>
<file alias="format_yolo">resources/icons/format_yolo.png</file>
<file alias="save-as">resources/icons/save-as.png</file>
<file alias="color">resources/icons/color.png</file>
<file alias="color_line">resources/icons/color_line.png</file>
<file alias="zoom">resources/icons/zoom.png</file>
<file alias="zoom-in">resources/icons/zoom-in.png</file>
<file alias="zoom-out">resources/icons/zoom-out.png</file>
<file alias="delete">resources/icons/cancel.png</file>
<file alias="next">resources/icons/next.png</file>
<file alias="prev">resources/icons/prev.png</file>
<file alias="resetall">resources/icons/resetall.png</file>
<file alias="verify">resources/icons/verify.png</file>
<file alias="strings">resources/strings/strings.properties</file>
<file alias="strings-zh-TW">resources/strings/strings-zh-TW.properties</file>
</qresource>
</RCC>
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
65 changes: 65 additions & 0 deletions resources/strings/strings-zh-TW.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
saveAsDetail=將標籤保存到其他文件
changeSaveDir=改變存放目錄
openFile=開啟檔案
shapeLineColorDetail=更改線條顏色
resetAll=重置
crtBox=創建區塊
crtBoxDetail=畫一個區塊
dupBoxDetail=複製區塊
verifyImg=驗證圖像
zoominDetail=放大
verifyImgDetail=驗證圖像
saveDetail=將標籤存到
openFileDetail=打開圖像
fitWidthDetail=調整到窗口寬度
tutorial=YouTube教學
editLabel=編輯標籤
openAnnotationDetail=打開標籤文件
quit=結束
shapeFillColorDetail=更改填充顏色
closeCurDetail=關閉目前檔案
closeCur=關閉
fitWin=調整到跟窗口一樣大小
delBox=刪除選取區塊
boxLineColorDetail=選擇框線顏色
originalsize=原始大小
resetAllDetail=重設所有設定
zoomoutDetail=畫面放大
save=儲存
saveAs=另存為
fitWinDetail=縮放到窗口一樣
openDir=開啟目錄
showHide=顯示/隱藏標籤
changeSaveFormat=更改儲存格式
shapeFillColor=填充顏色
quitApp=離開本程式
dupBox=複製區塊
delBoxDetail=刪除區塊
zoomin=放大畫面
info=資訊
openAnnotation=開啟標籤
prevImgDetail=上一個圖像
fitWidth=縮放到跟畫面一樣寬
zoomout=縮小畫面
changeSavedAnnotationDir=更改預設標籤存的目錄
nextImgDetail=下一個圖像
originalsizeDetail=放大到原始大小
prevImg=上一個圖像
tutorialDetail=顯示示範內容
shapeLineColor=形狀線條顏色
boxLineColor=日期分隔線顏色
editLabelDetail=修改所選區塊的標籤
nextImg=下一張圖片
useDefaultLabel=使用預設標籤
useDifficult=有難度的
boxLabelText=區塊的標籤
labels=標籤
autoSaveMode=自動儲存模式
singleClsMode=單一類別模式
displayLabel=顯示類別
fileList=檔案清單
files=檔案
advancedMode=進階模式
advancedModeDetail=切到進階模式
showAllBoxDetail=顯示所有區塊
hideAllBoxDetail=隱藏所有區塊
65 changes: 65 additions & 0 deletions resources/strings/strings.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
openFile=Open
openFileDetail=Open image or label file
quit=Quit
quitApp=Quit application
openDir=Open Dir
changeSavedAnnotationDir=Change default saved Annotation dir
openAnnotation=Open Annotation
openAnnotationDetail=Open an annotation file
changeSaveDir=Change Save Dir
nextImg=Next Image
nextImgDetail=Open the next Image
prevImg=Prev Image
prevImgDetail=Open the previous Image
verifyImg=Verify Image
verifyImgDetail=Verify Image
save=Save
saveDetail=Save the labels to a file
changeSaveFormat=Change save format
saveAs=Save As
saveAsDetail=Save the labels to a different file
closeCur=Close
closeCurDetail=Close the current file
resetAll=Reset All
resetAllDetail=Reset All
boxLineColor=Box Line Color
boxLineColorDetail=Choose Box line color
crtBox=Create\nRectBox
crtBoxDetail=Draw a new box
delBox=Delete\nRectBox
delBoxDetail=Remove the box
dupBox=Duplicate\nRectBox
dupBoxDetail=Create a duplicate of the selected box
tutorial=Tutorial
tutorialDetail=Show demo
info=Information
zoomin=Zoom In
zoominDetail=Increase zoom level
zoomout=Zoom Out
zoomoutDetail=Decrease zoom level
originalsize=Original size
originalsizeDetail=Zoom to original size
fitWin=Fit Window
fitWinDetail=Zoom follows window size
fitWidth=Fit Widith
fitWidthDetail=Zoom follows window width
editLabel=Edit Label
editLabelDetail=Modify the label of the selected Box
shapeLineColor=Shape Line Color
shapeLineColorDetail=Change the line color for this specific shape
shapeFillColor=Shape Fill Color
shapeFillColorDetail=Change the fill color for this specific shape
showHide=Show/Hide Label Panel
useDefaultLabel=Use default labtel
useDifficult=difficult
boxLabelText=Box Labels
labels=Labels
autoSaveMode=Auto Save mode
singleClsMode=Single Class Mode
displayLabel=Display Labels
fileList=File List
files=Files
advancedMode=Advanced Mode
advancedModeDetail=Swtich to advanced mode
showAllBoxDetail=Show all bounding boxes
hideAllBoxDetail=Hide all bounding boxes
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
APP = ['labelImg.py']
OPTIONS = {
'argv_emulation': True,
'iconfile': 'icons/app.icns'
'iconfile': 'resources/icons/app.icns'
}

setup(
Expand Down
15 changes: 15 additions & 0 deletions tests/test_lib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import os
import sys
import unittest
from libs.lib import struct, newAction, newIcon, addActions, fmtShortcut, generateColorByText

class TestLib(unittest.TestCase):

def test_generateColorByGivingUniceText_noError(self):
res = generateColorByText(u'\u958B\u555F\u76EE\u9304')
self.assertTrue(res.green() >= 0)
self.assertTrue(res.red() >= 0)
self.assertTrue(res.blue() >= 0)

if __name__ == '__main__':
unittest.main()
17 changes: 17 additions & 0 deletions tests/test_stringBundle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import os
import sys
import unittest
from stringBundle import StringBundle

class TestStringBundle(unittest.TestCase):

def test_loadDefaultBundle_withoutError(self):
strBundle = StringBundle.getBundle('en')
self.assertEqual(strBundle.getString("openDir"), 'Open Dir', 'Fail to load the default bundle')

def test_fallback_withoutError(self):
strBundle = StringBundle.getBundle('zh-TW')
self.assertEqual(strBundle.getString("openDir"), u'\u958B\u555F\u76EE\u9304', 'Fail to load the zh-TW bundle')

if __name__ == '__main__':
unittest.main()

0 comments on commit eaac031

Please sign in to comment.