大概在2月8日写完的工具,由于我是初学者加菜鸟,于是代码很长。其中包含解析用于对应back及arrow的xml文件,界面方面用了pyqt4,这个工具我主要用来学习了这2点,大致说下这个工具所使用到的QT控件:
QLineEdit:用户获得用户的输入路径及文件保存路径,获取QlineEdit值的method是:QLineEdit.text()即可,QLineEdit与QTextEdit获取值的方法不一样,QTextEdit的method是:QTextEdit.toPlainText(),TextEdit是个文本输入框,用户按下Tab键不会跳到下个焦点,于是我改用了QLineEidt。2个控件内容被更改后都会发送一个信号:stateChanged,使用connect即可连接到你需要处理的函数中,详细看代码,下面不在重复。
QCheckBox:获得checkbox的当前状态的method:checkState(),设定checkbox的新状态:setCheckState,2表示选中,0表示未选中。无论是程序设定还是用户勾选,当checkbox的状态被更改都会发射信号:stateChanged。其他简单空间基本相差不多。
QListWidget:QListWidget是一个对用户来说很方面的多选控件,建立2个ListWidget可以让用户很方便的在选中及忽略中切换需要的选项,其中QListWidget的Item可以选择在创建ui界面的时候设定,也可以在程序运行的过程中自动添加,首先来说一下Item的新增使用方法addItem,此方法提供的参数有2种,一种是直接把字符串传进去,也就是帮助中的label,另一种比较复杂是获得Item进行添加,由于是菜鸟,达到我的目的也就没有继续研究。相比之下,删除已有的Item就更复杂了,其中也有2个方法可以删除,一个是removeItemWidget(复杂未研究)另一个则是takeItem,takeItem需要1个int类型的row即可把对应的Item删除,例如想要删除从ListWidget迭代出来的Item,先要将用listWidget方法这个Item转换成ListWidget然后再使用row方法获取int row,最后使用takeItem即可删除,如下代码:takeItem(ignore.listWidget().row(ignore)),最后全部选中的方法是selectAll(),知道了这些,满足一般的基础的应用应该不成问题。
最后稍微提一下xml的读取使用minidom这个库,首先使用minidom.parse(xml)方法解析整个xml文档,然后使用parse_xml.getElementsByTagName('Object')可以获取所有的节点,使用node.getAttribute('ID')可以获得该节点的属性,相同的使用node.getElementsByTagName('ImageVariant')可以获得该节点的子节点,ImageVariant[1].childNodes[0].nodeValue则可以获得该节点的值。
1 #!/usr/bin/env python
2 #coding=utf-8
3
4 # data_copy
5
6 from PyQt4 import QtCore, QtGui
7 from data_copy import Ui_mainWindow
8
9 import gzip
10 import math
11 import win32gui
12 import win32con
13 from xml.dom import minidom
14
15
16 class data_copy_main(QtGui.QMainWindow):
17 def __init__(self):
18 super(data_copy_main, self).__init__()
19 self.form = Ui_mainWindow()
20 self.form.setupUi(self)
21 self.setFixedSize(579, 608)
22 self.form.progressBar.reset()
23 self.form.progressBar.setValue(0)
24
25 # Main Parameter
26 self.Cancel = 0
27 self.Message_text = ''
28 self.Message_error = ''
29 self.warningLabel = QtGui.QLabel()
30 self.exists_dataset = []
31 self.run_product = []
32 self.data_fomat = ['gdfas','gdf','shpd','shape','shapefile']
33 self.source_product = ['3dlm','3dlmlod1png','3dlmlod3png','jvlod1','jvlod3']
34 self.checkBoxlist = [self.form._3dlmlod1png,self.form._3dlmlod3png,self.form.jvlod1,self.form.jvlod3]
35 self.source_dataset = ['c11','c12','c13','c14','c15','c21','c22','c23','c31','c32','c33','c34','c35','c36','c37','c41','c42','c43','c44','c45','c46','c50','c51','c52','c53','c54','c61','c62','c63','c64','c65','c71','c81','c82']
36 self.especially_dataset = ['c71','c81','c82']
37 self.updata_label()
38
39 # Dataset Content QLineEdit
40 self.form.source_path_text.setFocus()
41 self.form.source_path_text.textChanged.connect(self.stdin_path_check)
42 self.form.source_path_text.textChanged.connect(self.active_checkbox)
43 self.form.new_path_text.textChanged.connect(self.active_groupbox)
44 self.form.new_path_text.textChanged.connect(self.active_checkbox)
45
46 # Dataset Content QCheckBox
47 self.form.All_Product.stateChanged.connect(self.click_all_product)
48 self.form.jvlod1.stateChanged.connect(self.active_groupbox)
49 self.form.jvlod3.stateChanged.connect(self.active_groupbox)
50 self.form._3dlmlod1png.stateChanged.connect(self.active_groupbox)
51 self.form._3dlmlod3png.stateChanged.connect(self.active_groupbox)
52
53 # Dataset Content QPushButton
54 self.form.Dataset_Content_OK.clicked.connect(self.run_copy)
55 self.form.Dataset_Content_Cancel.clicked.connect(self.Cancel_app)
56 self.form.SearchDataset.clicked.connect(self.add_datasetItem)
57
58 # Dataset Content QListWidget
59 self.form.copy_datasetlist.setSortingEnabled(True)
60 self.form.ignore_datasetlist.setSortingEnabled(True)
61 self.form.add_ignore.clicked.connect(self.add_ignore_list)
62 self.form.add_all_ignore.clicked.connect(self.add_all_ignore_list)
63 self.form.add_copy.clicked.connect(self.add_copy_list)
64 self.form.add_all_copy.clicked.connect(self.add_all_copy_list)
65
66 # Dataset Content QComboBox
67 self.form.Coverage_ComboBox.currentIndexChanged.connect(self.coverage_chaged)
68 self.form.Coverage_ComboBox.currentIndexChanged.connect(self.active_groupbox)
69
70 # Function
71 def warningMessage(self):
72 self.warningBox = QtGui.QMessageBox(QtGui.QMessageBox.Warning,u'警告', self.Message_error,QtGui.QMessageBox.NoButton, self)
73 self.warningBox.addButton("Continue", QtGui.QMessageBox.AcceptRole)
74 self.warningBox.addButton("Abort", QtGui.QMessageBox.RejectRole)
75 if self.warningBox.exec_() == QtGui.QMessageBox.AcceptRole:
76 self.warningLabel.setText("Continue")
77 else:
78 self.warningLabel.setText("Abort")
79
80 def errorMessage(self):
81 self.errorMessage = QtGui.QMessageBox(QtGui.QMessageBox.Warning,u'注意', self.Message_text,QtGui.QMessageBox.NoButton,self)
82 self.errorMessage.addButton("OK", QtGui.QMessageBox.AcceptRole)
83 self.errorMessage.exec_()
84
85 def run_copy(self):
86 self.form.run_state.setText(u'载入配置信息\n 请稍后……')
87 self.source_path = unicode(self.form.source_path_text.text())
88 self.save_path = unicode(self.form.new_path_text.text())
89 self.form.copy_datasetlist.selectAll()
90 self.selectedDataset = self.form.copy_datasetlist.selectedItems()
91 for checkbox in self.checkBoxlist:
92 if checkbox.checkState() == 2:
93 self.run_product.append(checkbox.text())
94 if os.path.exists(self.save_path) == False:
95 try:
96 os.makedirs(self.save_path)
97 except:
98 self.form.run_state.setText = u''
99 self.Message_text = u'保存路径不存在且无法创建,请确认!'
100 self.errorMessage()
101 return 0
102 else:
103 for olddir in os.listdir(self.save_path):
104 if olddir in self.run_product and os.path.exists(os.path.join(self.save_path,olddir)):
105 self.Message_error = u'警告:保存路径下存在与将要拷贝的产品同名的目录,是否全部删除?'
106 self.warningMessage()
107 if self.warningLabel.text() == 'Continue':
108 for deldir in os.listdir(self.save_path):
109 if deldir in self.run_product:
110 print type(self.save_path)
111 print type(deldir)
112 print type(os.path.join(self.save_path,deldir))
113 print os.path.join(self.save_path,deldir)
114 shutil.rmtree(os.path.join(self.save_path,deldir))
115 else:
116 return 0
117 product_count = 0
118 for product in self.run_product:
119 product = unicode(product)
120 product_alignment_display = '%s %s/%s'%(product,product_count,len(self.run_product))
121 self.form.run_state.setText(product_alignment_display)
122 self.copyCurrentDataset(product)
123 self.form.run_state.setText(u'')
124
125 def copyCurrentDataset(self,product):
126 self.form.run_state.setText(u'正在复制%s的Dataset ……' %(product))
127 if product == 'jvlod1' or 'jvldo3':
128 if self.form.Data_Format_ComboBox.currentText() != 'All Format':
129 Data_Format= unicode(self.form.Data_Format_ComboBox.currentText())
130 productPath = unicode(os.path.join(product,'sidefile','data','junctionviewlod' + product[-1],Data_Format))
131 scrdir = unicode(os.path.join(self.source_path,productPath))
132 dstdir = unicode(os.path.join(self.save_path,productPath))
133 self.copyDataset(scrdir,dstdir)
134 self.copyjunctionviewImage(product,dstdir)
135 else:
136 for Data_Format in self.data_fomat:
137 productPath = unicode(os.path.join(product,'sidefile','data','junctionviewlod' + product[-1],Data_Format))
138 if os.path.exists(os.path.join(self.source_path,productPath)):
139 scrdir = unicode(os.path.join(self.source_path,productPath))
140 dstdir = unicode(os.path.join(self.save_path,productPath))
141 self.copyDataset(scrdir,dstdir)
142 self.copyjunctionviewImage(product,dstdir)
143 else:
144 pass
145
146 def copyDataset(self,scrdir,dstdir):
147 self.form.progressBar.reset()
148 self.form.progressBar.setRange(0,100)
149 progressValue = float(100.00) / len(self.selectedDataset)
150 setValue = 0.00
151 copydataset_count = 0
152 for ready_copy in self.selectedDataset:
153 scr_datasetdir = unicode(os.path.join(scrdir,unicode(ready_copy.text())))
154 dst_datasetdir = unicode(os.path.join(dstdir,unicode(ready_copy.text())))
155 if os.path.exists(scr_datasetdir) == True:
156 copydataset_count += 1
157 setValue += progressValue
158 dataset_alignment_display = '%s/%s' %(copydataset_count,len(self.selectedDataset))
159 self.form.dataset_path.setText(scr_datasetdir)
160 self.form.dataset_count.setText(dataset_alignment_display)
161 shutil.copytree(scr_datasetdir,dst_datasetdir)
162 self.form.progressBar.setValue(setValue)
163 self.PeekMessage()
164 if self.Cancel != 0:
165 break
166 else:
167 pass
168 self.form.progressBar.setValue(100)
169
170 def copyjunctionviewImage(self,product,xmldir):
171 self.form.run_state.setText(u'准备复制Junctionview_Image\n正在载入sidefile信息\n请稍后……')
172 image_size = os.listdir(os.path.join(self.source_path,product))
173 try:
174 image_size.remove('sidefile')
175 except ValueError:
176 self.Message_text = u'Junctionview_sidefile未找到,请确认!'
177 self.errorMessage
178 return 0
179 if len(image_size) <= 0:
180 self.Message_text = u'图片大小信息缺失,请确认!'
181 self.errorMessage
182 return 0
183 jvdataset_num = os.listdir(xmldir)
184 jvdataset_count = 0
185 for dataset in jvdataset_num:
186 jvdataset_count += 1
187 jvdataset_alignment_display = '%s/%s' %(jvdataset_count,len(jvdataset_num))
188 self.form.dataset_count.setText(jvdataset_alignment_display)
189 copynow_dataset = os.path.join(xmldir,dataset)
190 self.form.dataset_path.setText(os.path.join(xmldir,dataset))
191 xml_list = os.listdir(os.path.join(xmldir,dataset))
192 for xml in xml_list:
193 if re.search(".txt.gz",xml):
194 continue
195 else:
196 self.form.file_path.setText(u'正在载入xml信息...')
197 format_name = xmldir.split('\\')[-2]
198 ungz_xml = gzip.open(os.path.join(xmldir,dataset,xml))
199 parse_xml = minidom.parse(ungz_xml)
200 object_node = parse_xml.getElementsByTagName('Object')
201 check_dict = {}
202 back_dict = {}
203 arrow_dict = {}
204 self.form.progressBar.reset()
205 self.form.progressBar.setRange(0.00,100.00)
206 setValue = 0
207 copyfile_num = 0
208 copyfile_now = 1
209 for node in object_node:
210 object_ID = node.getAttribute('ID')
211 ImageVariant = node.getElementsByTagName('ImageVariant')
212 back_path = ImageVariant[1].childNodes[0].nodeValue
213 arrow_path = ImageVariant[0].childNodes[0].nodeValue
214 if len(check_dict) == 0:
215 arrow_dict[object_ID] = arrow_path
216 back_dict[back_path] = arrow_dict
217 check_dict[object_ID] = back_dict
218 copyfile_num += 2
219 continue
220 for path in check_dict.itervalues():
221 add = 0
222 if path.has_key(back_path):
223 arrow_dict[object_ID] = arrow_path
224 copyfile_num += 1
225 add += 1
226 break
227 if add == 0:
228 arrow_dict = {}
229 back_dict = {}
230 arrow_dict[object_ID] = arrow_path
231 back_dict[back_path] = arrow_dict
232 check_dict[object_ID] = back_dict
233 copyfile_num += 2
234 else:
235 continue
236 coefficient = len(image_size)
237 try:
238 progressValue = float(100.00) / float(copyfile_num*coefficient)
239 except:
240 continue
241 setValue = 0
242 self.form.run_state.setText(u'正在复制关联图片……')
243 for size in image_size:
244 for backid in check_dict.iterkeys():
245 if self.Cancel !=0:
246 return 0
247 arrowdict_key = check_dict[backid].keys()[0]
248 back_split = arrowdict_key.split('\\')
249 srcfile = os.path.join(self.source_path,product,size,'chn\\all',back_split[4][-3:],back_split[3],back_split[4] + ".gz")
250 dstfile = os.path.join(self.save_path,product,size,'chn\\all',back_split[4][-3:],back_split[3],back_split[4] + ".gz")
251 setValue += progressValue
252 self.form.file_path.setText(srcfile)
253 self.form.file_num.setText('%s/%s' %(copyfile_now,copyfile_num*coefficient))
254 self.form.progressBar.setValue(setValue)
255 if os.path.exists(srcfile) == True:
256 self.mkdir_copy(srcfile,dstfile)
257 self.PeekMessage()
258 else:
259 print "%s,%s,%s,%s,%s,%s" %(product,dataset,backid,back_split[4] + ".gz",format_name,'back')
260 copyfile_now += 1
261 for arrowid in check_dict[backid][arrowdict_key].iterkeys():
262 if self.Cancel !=0:
263 return 0
264 arrow_split = check_dict[backid][arrowdict_key][arrowid].split('\\')
265 srcfile = os.path.join(self.source_path,product,size,'chn\\all',arrow_split[4][-3:],arrow_split[3],arrow_split[4] + ".gz")
266 dstfile = os.path.join(self.save_path,product,size,'chn\\all',arrow_split[4][-3:],arrow_split[3],arrow_split[4] + ".gz")
267 setValue += progressValue
268 self.form.file_path.setText(srcfile)
269 self.form.file_num.setText('%s/%s' %(copyfile_now,copyfile_num*coefficient))
270 self.form.progressBar.setValue(setValue)
271 copyfile_now += 1
272 if os.path.exists(srcfile) == True:
273 self.mkdir_copy(srcfile,dstfile)
274 self.PeekMessage()
275 else:
276 print "%s,%s,%s,%s,%s,%s,%s,%s" %(product,dataset,arrowid,arrow_split[4] + ".gz",backid,back_split[4] + ".gz",format_name,'arrow')
277 self.form.progressBar.setValue(100)
278 self.form.run_state.setText(u' 已完成')
279 self.Message_text = u'已成功复制关联图片'
280 self.errorMessage()
281
282 def mkdir_copy(self,srcfile,dstfile):
283 try:
284 shutil.copy(srcfile,dstfile)
285 except IOError:
286 os.makedirs(os.path.dirname(dstfile))
287 shutil.copy(srcfile,dstfile)
288
289 def Cancel_app(self):
290 self.Cancel += 1
291
292 def stdin_path_check(self):
293 self.form.All_Product.setEnabled(False)
294 self.form.All_Product.setCheckState(0)
295 for checkbox in self.checkBoxlist:
296 checkbox.setEnabled(False)
297 checkbox.setCheckState(0)
298 source_path = unicode(self.form.source_path_text.text())
299 dir_list = self.listdir_pass_error(source_path)
300 for dir in dir_list:
301 self.active_checkbox(dir)
302 if os.path.isdir(os.path.join(source_path,dir)):
303 dir_list_2 = self.listdir_pass_error(os.path.join(source_path,dir))
304 for dir_2 in dir_list_2:
305 self.active_checkbox(dir_2)
306 else:
307 continue
308
309 def add_datasetItem(self):
310 self.removeItemAll()
311 source_path = unicode(self.form.source_path_text.text())
312 for root,dirs,files in os.walk(source_path):
313 self.PeekMessage()
314 if len(self.exists_dataset) >= 34:
315 break
316 for dir in dirs:
317 if dir in self.source_dataset and dir not in self.exists_dataset:
318 self.exists_dataset.append(dir)
319 for item in self.exists_dataset:
320 self.form.copy_datasetlist.addItem(item)
321 self.form.select_dataset_label.setText(u'已选中%s个dataset' %(self.form.copy_datasetlist.count()))
322 self.form.ignore_dataset_label.setText(u'已忽略%s个dataset' %(self.form.ignore_datasetlist.count()))
323
324 def PeekMessage(self):
325 status, msg = win32gui.PeekMessage(self.winId(),0,0,win32con.PM_NOREMOVE)
326 if not msg[0] == 0:
327 b,msg = win32gui.GetMessage(self.winId(),0,0)
328 if msg:
329 win32gui.TranslateMessage(msg)
330 win32gui.DispatchMessage(msg)
331
332 def listdir_pass_error(self,dirname):
333 try:
334 return os.listdir(dirname)
335 except WindowsError:
336 pass
337
338 def click_all_product(self):
339 if self.form.All_Product.checkState() == 2:
340 for checkbox in self.checkBoxlist:
341 checkbox.setCheckState(2)
342 self.active_groupbox()
343 else:
344 for checkbox in self.checkBoxlist:
345 checkbox.setCheckState(0)
346 self.active_groupbox()
347
348 def add_copy_list(self):
349 self.copy_list = self.form.ignore_datasetlist.selectedItems()
350 for copy in self.copy_list:
351 self.form.copy_datasetlist.addItem(copy.text())
352 self.form.ignore_datasetlist.takeItem(copy.listWidget().row(copy))
353 self.updata_label()
354 self.active_groupbox()
355
356 def add_ignore_list(self):
357 self.ignore_list = self.form.copy_datasetlist.selectedItems()
358 for ignore in self.ignore_list:
359 self.form.ignore_datasetlist.addItem(ignore.text())
360 self.form.copy_datasetlist.takeItem(ignore.listWidget().row(ignore))
361 self.updata_label()
362 self.active_groupbox()
363
364 def add_all_ignore_list(self):
365 self.form.copy_datasetlist.selectAll()
366 self.add_ignore_list()
367
368 def add_all_copy_list(self):
369 self.form.ignore_datasetlist.selectAll()
370 self.add_copy_list()
371
372 def removeItemAll(self):
373 self.form.copy_datasetlist.selectAll()
374 self.form.ignore_datasetlist.selectAll()
375 remove_selected = self.form.copy_datasetlist.selectedItems()
376 remove_ignore = self.form.ignore_datasetlist.selectedItems()
377 for item in remove_selected:
378 self.form.copy_datasetlist.takeItem(item.listWidget().row(item))
379 for item in remove_ignore:
380 self.form.ignore_datasetlist.takeItem(item.listWidget().row(item))
381 self.actually_product = []
382 self.form.select_dataset_label.setText(u'将执行的Dataset列表')
383 self.form.ignore_dataset_label.setText(u'将忽略的Dataset列表')
384
385 def active_groupbox(self):
386 new_path = self.form.new_path_text.text()
387 checkboxstate = 0
388 for checkbox in self.checkBoxlist:
389 if checkbox.checkState():
390 checkboxstate += 1
391 break
392 self.form.Dataset_Content_OK.setEnabled(bool(self.form.copy_datasetlist.count() and new_path and checkboxstate))
393
394 def active_checkbox(self,dirname):
395 if dirname in self.source_product:
396 for checkbox in self.checkBoxlist:
397 if dirname == checkbox.text():
398 checkbox.setEnabled(True)
399 self.active_groupbox()
400 for checkbox in self.checkBoxlist:
401 if checkbox.isEnabled():
402 self.form.All_Product.setEnabled(True)
403 break
404
405 def updata_label(self):
406 self.form.select_dataset_label.setText(u'已选中%s个dataset' %(self.form.copy_datasetlist.count()))
407 self.form.ignore_dataset_label.setText(u'已忽略%s个dataset' %(self.form.ignore_datasetlist.count()))
408
409 def coverage_chaged(self):
410 if self.form.Coverage_ComboBox.currentText() == 'Full China':
411 self.add_all_copy_list()
412 elif self.form.Coverage_ComboBox.currentText() == 'China Mainland':
413 self.add_all_copy_list()
414 self.form.copy_datasetlist.selectAll()
415 takeorder_list = self.form.copy_datasetlist.selectedItems()
416 for item in takeorder_list:
417 if item.text() in self.especially_dataset:
418 self.form.ignore_datasetlist.addItem(item.text())
419 self.form.copy_datasetlist.takeItem(item.listWidget().row(item))
420 self.form.copy_datasetlist.clearSelection()
421 elif self.form.Coverage_ComboBox.currentText() == 'HKG + MAC':
422 self.add_all_ignore_list()
423 self.form.ignore_datasetlist.selectAll()
424 takeorder_list = self.form.ignore_datasetlist.selectedItems()
425 for item in takeorder_list:
426 if item.text() in self.especially_dataset:
427 self.form.copy_datasetlist.addItem(item.text())
428 self.form.ignore_datasetlist.takeItem(item.listWidget().row(item))
429 self.form.ignore_datasetlist.clearSelection()
430 self.updata_label()
431
432 if __name__ == '__main__':
433 import os,sys,repr,re,gzip,shutil
434 import functools
435 import copy
436 app = QtGui.QApplication(sys.argv)
437 win_copy = data_copy_main()
438 win_copy.show()
439 sys.exit(app.exec_())