개정판 e4b3e191
fixed issue #480: 라인 인식
DTI_PID/DTI_PID/App.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
|
|
3 |
import sys |
|
4 |
import os |
|
5 |
import cv2 |
|
6 |
|
|
7 |
from PyQt5.QtCore import * |
|
8 |
from PyQt5.QtGui import * |
|
9 |
from PyQt5.QtWidgets import * |
|
10 |
from PyQt5.QtSvg import * |
|
11 |
|
|
12 |
import DTI_PID_UI |
|
13 |
import QtImageViewer |
|
14 |
|
|
15 |
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands') |
|
16 |
import CreateCommand |
|
17 |
import CropCommand |
|
18 |
|
|
19 |
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Shapes') |
|
20 |
import QGraphicsPolylineItem |
|
21 |
from QEngineeringLineItem import QEngineeringLineItem |
|
22 |
from SymbolSvg import SymbolSvg |
|
23 |
from QGraphicsBoundingBoxItem import QGraphicsBoundingBoxItem |
|
24 |
|
|
25 |
class Worker(QObject): |
|
26 |
from PyQt5.QtCore import QThread |
|
27 |
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QGridLayout |
|
28 |
import sys |
|
29 |
from DTI_PID import executeRecognition |
|
30 |
|
|
31 |
finished = pyqtSignal() |
|
32 |
intReady = pyqtSignal(int) |
|
33 |
|
|
34 |
#pyqtSlot() |
|
35 |
def procCounter(self): # A slot takes no params |
|
36 |
from DTI_PID import executeRecognition |
|
37 |
|
|
38 |
try: |
|
39 |
self.xmlPath = executeRecognition(self.path, self.listWidget) |
|
40 |
self.finished.emit() |
|
41 |
except Exception as ex: |
|
42 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
43 |
|
|
44 |
class SingletonInstane: |
|
45 |
__instance = None |
|
46 |
|
|
47 |
@classmethod |
|
48 |
def __getInstance(cls): |
|
49 |
return cls.__instance |
|
50 |
|
|
51 |
@classmethod |
|
52 |
def instance(cls, *args, **kargs): |
|
53 |
cls.__instance = cls(*args, **kargs) |
|
54 |
cls.instance = cls.__getInstance |
|
55 |
return cls.__instance |
|
56 |
|
|
57 |
class ExampleApp(QMainWindow, DTI_PID_UI.Ui_MainWindow, SingletonInstane): |
|
58 |
def __init__(self): |
|
59 |
super(self.__class__, self).__init__() |
|
60 |
self.setupUi(self) |
|
61 |
self.lineComboBox = QComboBox(self.toolBar) |
|
62 |
self.lineComboBox.addItem('Primary Line') |
|
63 |
self.lineComboBox.addItem('Secondary Line') |
|
64 |
self.lineComboBox.addItem('Utility Line') |
|
65 |
self.toolBar.insertWidget(self.actionValidate, self.lineComboBox) |
|
66 |
self.toolBar.insertSeparator(self.actionValidate) |
|
67 |
self.graphicsView = QtImageViewer.QtImageViewer() |
|
68 |
self.graphicsView.setParent(self.centralwidget) |
|
69 |
self.verticalLayout.addWidget(self.graphicsView) |
|
70 |
|
|
71 |
# connect signals and slots |
|
72 |
self.actionClose.triggered.connect(self.close) |
|
73 |
self.actionOpen.triggered.connect(self.openImageDrawing) |
|
74 |
self.actionEqpNozzle.triggered.connect(self.connectEqpNozzle) |
|
75 |
self.actionLine.triggered.connect(self.createLine) |
|
76 |
self.actionRecognition.triggered.connect(self.recognize) |
|
77 |
self.actionConfiguration.triggered.connect(self.configuration) |
|
78 |
|
|
79 |
''' |
|
80 |
@brief configuration |
|
81 |
''' |
|
82 |
def configuration(self): |
|
83 |
from QConfigurationDialog import QConfigurationDialog |
|
84 |
|
|
85 |
self.dlgConfiguration = QConfigurationDialog(self) |
|
86 |
self.dlgConfiguration.show() |
|
87 |
self.dlgConfiguration.exec_() |
|
88 |
|
|
89 |
''' |
|
90 |
@brief Open image drawing file and then display it |
|
91 |
''' |
|
92 |
def openImageDrawing(self, MainWindow): |
|
93 |
self.path = self.graphicsView.loadImageFromFile() |
|
94 |
|
|
95 |
svg = SymbolSvg() |
|
96 |
svg.setPos(100,100) |
|
97 |
self.graphicsView.scene.addItem(svg) |
|
98 |
|
|
99 |
# DEBUG |
|
100 |
''' |
|
101 |
from LineDetector import LineDetector |
|
102 |
self.loadRecognitionResult('d:\\Projects\\DTIPID\\DTI_PID\\DTI_PID\\res\\Result\\UY1-K-2007_P1_300dpi_black.xml') |
|
103 |
|
|
104 |
# detect line |
|
105 |
img = cv2.imread(self.path) |
|
106 |
detector = LineDetector(img) |
|
107 |
for item in self.graphicsView.scene.items(): |
|
108 |
if type(item) is QGraphicsBoundingBoxItem: |
|
109 |
res = detector.Detect(item) |
|
110 |
for pts in res: |
|
111 |
line = QEngineeringLineItem() |
|
112 |
line._vertices.append(QPointF(pts[0][0], pts[0][1])) |
|
113 |
line._vertices.append(QPointF(pts[1][0], pts[1][1])) |
|
114 |
self.graphicsView.scene.addItem(line) |
|
115 |
|
|
116 |
detector.save() |
|
117 |
''' |
|
118 |
# up to here |
|
119 |
|
|
120 |
return self.path |
|
121 |
|
|
122 |
''' |
|
123 |
@brief connect equipment and nozzle |
|
124 |
''' |
|
125 |
def connectEqpNozzle(self): |
|
126 |
self.graphicsView.command = None |
|
127 |
|
|
128 |
''' |
|
129 |
@brief create a line |
|
130 |
''' |
|
131 |
def createLine(self): |
|
132 |
# set imageviewer's command |
|
133 |
self.graphicsView.command = CreateCommand.CreateCommand(self.graphicsView, QEngineeringLineItem()) |
|
134 |
# up to here |
|
135 |
|
|
136 |
''' |
|
137 |
@brief recognize symbol and text |
|
138 |
''' |
|
139 |
def recognize(self, MainWindow): |
|
140 |
from QRecognitionDialog import QRecognitionDialog |
|
141 |
from LineDetector import LineDetector |
|
142 |
|
|
143 |
try: |
|
144 |
self.dlg = QRecognitionDialog(self) |
|
145 |
self.startThread() |
|
146 |
self.dlg.show() |
|
147 |
self.dlg.exec_() |
|
148 |
|
|
149 |
if self.dlg.isAccepted == True: |
|
150 |
self.loadRecognitionResult(self.xmlPath[0]) |
|
151 |
|
|
152 |
# detect line |
|
153 |
img = cv2.imread(self.path) |
|
154 |
detector = LineDetector(img) |
|
155 |
for item in self.graphicsView.scene.items(): |
|
156 |
if (type(item) is QGraphicsBoundingBoxItem) and item.isSymbol: |
|
157 |
res = detector.Detect(item) |
|
158 |
for pts in res: |
|
159 |
line = QEngineeringLineItem() |
|
160 |
line._vertices.append(QPointF(pts[0][0], pts[0][1])) |
|
161 |
line._vertices.append(QPointF(pts[1][0], pts[1][1])) |
|
162 |
self.graphicsView.scene.addItem(line) |
|
163 |
# up to here |
|
164 |
except Exception as ex: |
|
165 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
166 |
|
|
167 |
''' |
|
168 |
@brief load recognition result |
|
169 |
''' |
|
170 |
def loadRecognitionResult(self, xmlPath): |
|
171 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree, parse |
|
172 |
|
|
173 |
try: |
|
174 |
xml = parse(xmlPath) |
|
175 |
root = xml.getroot(); |
|
176 |
for symbol in root.iter('SYMBOL'): |
|
177 |
pt = symbol.find('STARTPOINT').text.split(',') |
|
178 |
size = symbol.find('SIZE').text.split(',') |
|
179 |
item = QGraphicsBoundingBoxItem(float(pt[0]), float(pt[1]), float(size[0]), float(size[1])) |
|
180 |
item.isSymbol = True |
|
181 |
item.angle = float(symbol.find('ANGLE').text) |
|
182 |
item.setPen(QPen(Qt.red, 20, Qt.SolidLine)) |
|
183 |
self.graphicsView.scene.addItem(item) |
|
184 |
''' |
|
185 |
for text in root.iter('TEXTINFO'): |
|
186 |
x = float(text.find('X').text) |
|
187 |
y = float(text.find('Y').text) |
|
188 |
width = float(text.find('WIDTH').text) |
|
189 |
height = float(text.find('HEIGHT').text) |
|
190 |
item = QGraphicsBoundingBoxItem(x, y, width, height) |
|
191 |
item.setPen(QPen(Qt.blue, 20, Qt.SolidLine)) |
|
192 |
self.graphicsView.scene.addItem(item) |
|
193 |
''' |
|
194 |
except Exception as ex: |
|
195 |
print('error occured {} as at {0}'.format(ex, sys.exc_info()[-1].tb_lineno)) |
|
196 |
|
|
197 |
''' |
|
198 |
@brief start thread |
|
199 |
''' |
|
200 |
def startThread(self): |
|
201 |
self.dlg.ui.buttonBox.setDisabled(True) |
|
202 |
|
|
203 |
# 1 - create Worker and Thread inside the Form |
|
204 |
self.obj = Worker() # no parent! |
|
205 |
self.obj.path = self.path |
|
206 |
self.obj.listWidget = self.dlg.ui.listWidget |
|
207 |
self.thread = QThread() # no parent! |
|
208 |
|
|
209 |
# 2 - Connect Worker`s Signals to Form method slots to post data. |
|
210 |
#self.obj.intReady.connect(self.onIntReady) |
|
211 |
|
|
212 |
# 3 - Move the Worker object to the Thread object |
|
213 |
self.obj.moveToThread(self.thread) |
|
214 |
|
|
215 |
# 4 - Connect Worker Signals to the Thread slots |
|
216 |
self.obj.finished.connect(self.thread.quit) |
|
217 |
|
|
218 |
# 5 - Connect Thread started signal to Worker operational slot method |
|
219 |
self.thread.started.connect(self.obj.procCounter) |
|
220 |
|
|
221 |
# * - Thread finished signal will close the app if you want! |
|
222 |
self.thread.finished.connect(self.dlgExit) |
|
223 |
|
|
224 |
# 6 - Start the thread |
|
225 |
self.thread.start() |
|
226 |
|
|
227 |
''' |
|
228 |
@brief set buttonbox's enabled flag |
|
229 |
''' |
|
230 |
def dlgExit(self): |
|
231 |
self.xmlPath = self.obj.xmlPath |
|
232 |
self.dlg.ui.buttonBox.setEnabled(True) |
|
233 |
|
|
234 |
if __name__ == '__main__': |
|
235 |
import DTI_PID_UI |
|
236 |
from ProjectDialog import Ui_Dialog |
|
237 |
|
|
238 |
app = QApplication(sys.argv) |
|
239 |
|
|
240 |
try: |
|
241 |
dlg = Ui_Dialog() |
|
242 |
dlg.show() |
|
243 |
dlg.exec_() |
|
244 |
if dlg.selectedProject is not None: |
|
245 |
form = ExampleApp.instance() |
|
246 |
form.show() |
|
247 |
except Exception as ex: |
|
248 |
print('에러가 발생했습니다.\n', ex) |
|
249 |
|
|
250 |
sys.exit(app.exec_()) |
DTI_PID/DTI_PID/AppDocData.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
|
|
3 |
import os |
|
4 |
import sqlite3 |
|
5 |
from SingletonInstance import SingletonInstane |
|
6 |
|
|
7 |
DB_NAME = os.path.dirname(os.path.realpath(__file__)) + "\\db\\DTI_PID.db" |
|
8 |
|
|
9 |
class AppDocData(SingletonInstane): |
|
10 |
''' |
|
11 |
@brief get sliding window size |
|
12 |
''' |
|
13 |
def getSlidingWindowSize(self): |
|
14 |
res = [10,10] |
|
15 |
try: |
|
16 |
# Creates or opens a file called mydb with a SQLite3 DB |
|
17 |
db = sqlite3.connect(DB_NAME) |
|
18 |
# Get a cursor object |
|
19 |
cursor = db.cursor() |
|
20 |
|
|
21 |
sql = "select * from configuration where section='Sliding Window'" |
|
22 |
cursor.execute(sql) |
|
23 |
rows = cursor.fetchall() |
|
24 |
for row in rows: |
|
25 |
if row[1] == 'Width': |
|
26 |
res[0] = int(row[2]) |
|
27 |
elif row[1] == 'Height': |
|
28 |
res[1] = int(row[2]) |
|
29 |
# Catch the exception |
|
30 |
except Exception as e: |
|
31 |
# Roll back any change if something goes wrong |
|
32 |
db.rollback() |
|
33 |
raise e |
|
34 |
finally: |
|
35 |
# Close the db connection |
|
36 |
db.close() |
|
37 |
|
|
38 |
return res |
|
39 |
|
|
40 |
pass |
DTI_PID/DTI_PID/DTI_PID.py | ||
---|---|---|
719 | 719 |
|
720 | 720 |
|
721 | 721 |
#Main function |
722 |
def main(path, listWidget):
|
|
722 |
def executeRecognition(path, listWidget):
|
|
723 | 723 |
global src |
724 | 724 |
global srcGray |
725 | 725 |
global ocrCompletedSrc |
... | ... | |
818 | 818 |
|
819 | 819 |
return res |
820 | 820 |
|
821 |
class Worker(QObject): |
|
822 |
from PyQt5.QtCore import QThread |
|
823 |
from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QGridLayout |
|
824 |
import sys |
|
825 |
|
|
826 |
finished = pyqtSignal() |
|
827 |
intReady = pyqtSignal(int) |
|
828 |
|
|
829 |
#pyqtSlot() |
|
830 |
def procCounter(self): # A slot takes no params |
|
831 |
self.xmlPath = main(self.path, self.listWidget) |
|
832 |
self.finished.emit() |
|
833 |
|
|
834 |
class ExampleApp(QMainWindow, DTI_PID_UI.Ui_MainWindow): |
|
835 |
def __init__(self): |
|
836 |
super(self.__class__, self).__init__() |
|
837 |
self.setupUi(self) |
|
838 |
self.lineComboBox = QComboBox(self.toolBar) |
|
839 |
self.lineComboBox.addItem('Primary Line') |
|
840 |
self.lineComboBox.addItem('Secondary Line') |
|
841 |
self.lineComboBox.addItem('Utility Line') |
|
842 |
self.toolBar.insertWidget(self.actionValidate, self.lineComboBox) |
|
843 |
self.toolBar.insertSeparator(self.actionValidate) |
|
844 |
self.graphicsView = QtImageViewer.QtImageViewer() |
|
845 |
self.graphicsView.setParent(self.centralwidget) |
|
846 |
self.verticalLayout.addWidget(self.graphicsView) |
|
847 |
|
|
848 |
# connect signals and slots |
|
849 |
self.actionClose.triggered.connect(self.close) |
|
850 |
self.actionOpen.triggered.connect(self.openImageDrawing) |
|
851 |
self.actionEqpNozzle.triggered.connect(self.connectEqpNozzle) |
|
852 |
self.actionLine.triggered.connect(self.createLine) |
|
853 |
self.actionRecognition.triggered.connect(self.recognize) |
|
854 |
self.actionConfiguration.triggered.connect(self.configuration) |
|
855 |
|
|
856 |
''' |
|
857 |
@brief configuration |
|
858 |
''' |
|
859 |
def configuration(self): |
|
860 |
from QConfigurationDialog import QConfigurationDialog |
|
861 |
|
|
862 |
self.dlgConfiguration = QConfigurationDialog(self) |
|
863 |
self.dlgConfiguration.show() |
|
864 |
self.dlgConfiguration.exec_() |
|
865 |
|
|
866 |
''' |
|
867 |
@brief Open image drawing file and then display it |
|
868 |
''' |
|
869 |
def openImageDrawing(self, MainWindow): |
|
870 |
self.path = self.graphicsView.loadImageFromFile() |
|
871 |
|
|
872 |
svg = SymbolSvg() |
|
873 |
svg.setPos(100,100) |
|
874 |
self.graphicsView.scene.addItem(svg) |
|
875 |
|
|
876 |
# DEBUG |
|
877 |
''' |
|
878 |
from LineDetector import LineDetector |
|
879 |
self.loadRecognitionResult('d:\\Projects\\DTIPID\\DTI_PID\\DTI_PID\\res\\Result\\UY1-K-2007_P1_300dpi_black.xml') |
|
880 |
|
|
881 |
# detect line |
|
882 |
img = cv2.imread(self.path) |
|
883 |
detector = LineDetector(img) |
|
884 |
for item in self.graphicsView.scene.items(): |
|
885 |
if type(item) is QGraphicsBoundingBoxItem: |
|
886 |
res = detector.Detect(item) |
|
887 |
for pts in res: |
|
888 |
line = QEngineeringLineItem() |
|
889 |
line._vertices.append(QPointF(pts[0][0], pts[0][1])) |
|
890 |
line._vertices.append(QPointF(pts[1][0], pts[1][1])) |
|
891 |
self.graphicsView.scene.addItem(line) |
|
892 |
|
|
893 |
detector.save() |
|
894 |
''' |
|
895 |
# up to here |
|
896 |
|
|
897 |
return self.path |
|
898 |
|
|
899 |
''' |
|
900 |
@brief connect equipment and nozzle |
|
901 |
''' |
|
902 |
def connectEqpNozzle(self): |
|
903 |
self.graphicsView.command = None |
|
904 |
|
|
905 |
''' |
|
906 |
@brief create a line |
|
907 |
''' |
|
908 |
def createLine(self): |
|
909 |
# set imageviewer's command |
|
910 |
self.graphicsView.command = CreateCommand.CreateCommand(self.graphicsView, QEngineeringLineItem()) |
|
911 |
# up to here |
|
912 |
|
|
913 |
''' |
|
914 |
@brief recognize symbol and text |
|
915 |
''' |
|
916 |
def recognize(self, MainWindow): |
|
917 |
from QRecognitionDialog import QRecognitionDialog |
|
918 |
from LineDetector import LineDetector |
|
919 |
|
|
920 |
try: |
|
921 |
self.dlg = QRecognitionDialog(self) |
|
922 |
self.startThread() |
|
923 |
self.dlg.show() |
|
924 |
self.dlg.exec_() |
|
925 |
|
|
926 |
if self.dlg.isAccepted == True: |
|
927 |
self.loadRecognitionResult(self.xmlPath[0]) |
|
928 |
|
|
929 |
# detect line |
|
930 |
img = cv2.imread(self.path) |
|
931 |
detector = LineDetector(img) |
|
932 |
for item in self.graphicsView.scene.items(): |
|
933 |
if (type(item) is QGraphicsBoundingBoxItem) and item.isSymbol: |
|
934 |
res = detector.Detect(item) |
|
935 |
for pts in res: |
|
936 |
line = QEngineeringLineItem() |
|
937 |
line._vertices.append(QPointF(pts[0][0], pts[0][1])) |
|
938 |
line._vertices.append(QPointF(pts[1][0], pts[1][1])) |
|
939 |
self.graphicsView.scene.addItem(line) |
|
940 |
# up to here |
|
941 |
except Exception as ex: |
|
942 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
943 |
|
|
944 |
''' |
|
945 |
@brief load recognition result |
|
946 |
''' |
|
947 |
def loadRecognitionResult(self, xmlPath): |
|
948 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree, parse |
|
949 |
|
|
950 |
try: |
|
951 |
xml = parse(xmlPath) |
|
952 |
root = xml.getroot(); |
|
953 |
for symbol in root.iter('SYMBOL'): |
|
954 |
pt = symbol.find('STARTPOINT').text.split(',') |
|
955 |
size = symbol.find('SIZE').text.split(',') |
|
956 |
item = QGraphicsBoundingBoxItem(float(pt[0]), float(pt[1]), float(size[0]), float(size[1])) |
|
957 |
item.isSymbol = True |
|
958 |
item.angle = float(symbol.find('ANGLE').text) |
|
959 |
item.setPen(QPen(Qt.red, 20, Qt.SolidLine)) |
|
960 |
self.graphicsView.scene.addItem(item) |
|
961 |
''' |
|
962 |
for text in root.iter('TEXTINFO'): |
|
963 |
x = float(text.find('X').text) |
|
964 |
y = float(text.find('Y').text) |
|
965 |
width = float(text.find('WIDTH').text) |
|
966 |
height = float(text.find('HEIGHT').text) |
|
967 |
item = QGraphicsBoundingBoxItem(x, y, width, height) |
|
968 |
item.setPen(QPen(Qt.blue, 20, Qt.SolidLine)) |
|
969 |
self.graphicsView.scene.addItem(item) |
|
970 |
''' |
|
971 |
except Exception as ex: |
|
972 |
print('error occured {} as at {0}'.format(ex, sys.exc_info()[-1].tb_lineno)) |
|
973 |
|
|
974 |
''' |
|
975 |
@brief start thread |
|
976 |
''' |
|
977 |
def startThread(self): |
|
978 |
self.dlg.ui.buttonBox.setDisabled(True) |
|
979 |
|
|
980 |
# 1 - create Worker and Thread inside the Form |
|
981 |
self.obj = Worker() # no parent! |
|
982 |
self.obj.path = self.path |
|
983 |
self.obj.listWidget = self.dlg.ui.listWidget |
|
984 |
self.thread = QThread() # no parent! |
|
985 |
|
|
986 |
# 2 - Connect Worker`s Signals to Form method slots to post data. |
|
987 |
#self.obj.intReady.connect(self.onIntReady) |
|
988 |
|
|
989 |
# 3 - Move the Worker object to the Thread object |
|
990 |
self.obj.moveToThread(self.thread) |
|
991 |
|
|
992 |
# 4 - Connect Worker Signals to the Thread slots |
|
993 |
self.obj.finished.connect(self.thread.quit) |
|
994 |
|
|
995 |
# 5 - Connect Thread started signal to Worker operational slot method |
|
996 |
self.thread.started.connect(self.obj.procCounter) |
|
997 |
|
|
998 |
# * - Thread finished signal will close the app if you want! |
|
999 |
self.thread.finished.connect(self.dlgExit) |
|
1000 |
|
|
1001 |
# 6 - Start the thread |
|
1002 |
self.thread.start() |
|
1003 |
|
|
1004 |
''' |
|
1005 |
@brief set buttonbox's enabled flag |
|
1006 |
''' |
|
1007 |
def dlgExit(self): |
|
1008 |
self.xmlPath = self.obj.xmlPath |
|
1009 |
self.dlg.ui.buttonBox.setEnabled(True) |
|
1010 |
|
|
1011 | 821 |
if __name__ == '__main__': |
1012 | 822 |
import DTI_PID_UI |
1013 | 823 |
from ProjectDialog import Ui_Dialog |
DTI_PID/DTI_PID/LineDetector.py | ||
---|---|---|
143 | 143 |
''' |
144 | 144 |
def Detect(self, symbol): |
145 | 145 |
res = [] |
146 |
#white = [255,255,255] |
|
147 | 146 |
|
148 | 147 |
try: |
149 | 148 |
pool = [] |
... | ... | |
186 | 185 |
@brief detect a line along given direction |
187 | 186 |
''' |
188 | 187 |
def detectLine(self, pt, dir): |
188 |
from AppDocData import AppDocData |
|
189 |
|
|
189 | 190 |
white = [255,255,255] |
190 |
windowSize = [20,10]
|
|
191 |
windowSize = AppDocData.instance().getSlidingWindowSize()
|
|
191 | 192 |
xHalf = int(windowSize[0]*0.5) |
192 | 193 |
yHalf = int(windowSize[1]*0.5) |
193 | 194 |
|
DTI_PID/DTI_PID/SingletonInstance.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
|
|
3 |
class SingletonInstane: |
|
4 |
__instance = None |
|
5 |
|
|
6 |
@classmethod |
|
7 |
def __getInstance(cls): |
|
8 |
return cls.__instance |
|
9 |
|
|
10 |
@classmethod |
|
11 |
def instance(cls, *args, **kargs): |
|
12 |
cls.__instance = cls(*args, **kargs) |
|
13 |
cls.instance = cls.__getInstance |
|
14 |
return cls.__instance |
내보내기 Unified diff