控制网复测平面基准归算程序(包含控制网复测平面基准计算,平面控制网稳定性计算,水准测段高差稳定计算三个程序功能)
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

main_new.py 43KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981
  1. # ///////////////////////////////////////////////////////////////
  2. #
  3. # BY: WANDERSON M.PIMENTA
  4. # PROJECT MADE WITH: Qt Designer and PySide6
  5. # V: 1.0.0
  6. #
  7. # This project can be used freely for all uses, as long as they maintain the
  8. # respective credits only in the Python scripts, any information in the visual
  9. # interface (GUI) can be modified without any implication.
  10. #
  11. # There are limitations on Qt licenses if you want to use your products
  12. # commercially, I recommend reading them on the official website:
  13. # https://doc.qt.io/qtforpython/licenses.html
  14. #
  15. # ///////////////////////////////////////////////////////////////
  16. from idlelib.searchengine import search_reverse
  17. from PySide6.QtWidgets import QFileDialog,QWidget, QVBoxLayout, QTreeWidget, QApplication, QTreeWidgetItem
  18. from PySide6.QtCore import Signal, Qt, Slot, QObject
  19. from PySide6.QtSql import QSqlTableModel,QSqlDatabase
  20. import sqlite3
  21. from PySide6.QtGui import QIcon
  22. import sys
  23. import os
  24. import platform
  25. from tkinter import messagebox
  26. # IMPORT / GUI AND MODULES AND WIDGETS
  27. # ///////////////////////////////////////////////////////////////
  28. from modules import *
  29. from widgets import *
  30. os.environ["QT_FONT_DPI"] = "96" # FIX Problem for High DPI and Scale above 100%
  31. # SET AS GLOBAL WIDGETS
  32. # ///////////////////////////////////////////////////////////////
  33. widgets = None
  34. excelname = ''
  35. # 获取项目根目录
  36. project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
  37. # 将项目根目录添加到 sys.path
  38. sys.path.append(project_root)
  39. # 表格的模型
  40. class MyTableModel(QAbstractTableModel):
  41. def __init__(self, data):
  42. super().__init__()
  43. self._data = data
  44. # 重新定义行数
  45. def rowCount(self, parent=QModelIndex()):
  46. return len(self._data)
  47. # 重新定义列数
  48. def columnCount(self, parent=QModelIndex()):
  49. return len(self._data[0]) if self._data else 0
  50. # 重新定义数据
  51. def data(self, index, role=Qt.DisplayRole):
  52. if not index.isValid():
  53. return None
  54. if role == Qt.DisplayRole:
  55. return self._data[index.row()][index.column()]
  56. return None
  57. class TreeWidgetItem:
  58. def __init__(self, id: any, parent_id: any, name: str,icon: QIcon = None, extend: object = None):
  59. """
  60. 菜单数据接口
  61. :param id: ID
  62. :param parent_id: 父ID
  63. :param name: 菜单名称
  64. :param icon: 图标
  65. :param extend: 扩展数据
  66. """
  67. self.id: any = id
  68. self.parent_id: any = parent_id
  69. self.name: str = name
  70. self.extend: object = extend
  71. # 实例化
  72. self.treeWidgetItem = QTreeWidgetItem([self.name])
  73. # 存储相关数据
  74. self.treeWidgetItem.setData(0, Qt.UserRole + 1,extend )
  75. self.treeWidgetItem.setIcon(0, QIcon(':/icons/default.png'))
  76. if icon is not None:
  77. self.treeWidgetItem.setIcon(0, icon)
  78. class ElTreeData(QObject):
  79. """
  80. Data Model
  81. """
  82. items_changed: Signal = Signal(str)
  83. styleSheet_changed: Signal = Signal(str)
  84. def __init__(self, items: list[TreeWidgetItem] = None, styleSheet: str = None):
  85. super(ElTreeData, self).__init__()
  86. # 定义数据
  87. self._items: list[TreeWidgetItem]
  88. self._styleSheet: str
  89. # 初始化数据
  90. self.items = items
  91. self.styleSheet = styleSheet
  92. @property
  93. def items(self):
  94. return self._items
  95. @items.setter
  96. def items(self, value):
  97. self._items = value
  98. # 数据改变时发出信号
  99. self.items_changed.emit(self.items)
  100. @property
  101. def styleSheet(self):
  102. return self._styleSheet
  103. @styleSheet.setter
  104. def styleSheet(self, value):
  105. self._styleSheet = value
  106. # 数据改变时发出信号
  107. self.styleSheet_changed.emit(self.styleSheet)
  108. #全数据库
  109. class ElTree(QWidget):
  110. """
  111. Control
  112. """
  113. itemClicked: Signal = Signal(object)
  114. itemDoubleClicked: Signal = Signal(object)
  115. def __init__(self, treeData: ElTreeData, parent=None):
  116. super(ElTree, self).__init__(parent=parent)
  117. self.data = treeData
  118. # 将按钮的点击信号绑定到当前类的点击信号
  119. widgets.allTreeWidget.itemClicked.connect(lambda item: self.itemClicked.emit(item.data(0, Qt.UserRole + 1)))
  120. widgets.allTreeWidget.itemDoubleClicked.connect(lambda item: self.itemDoubleClicked.emit(item.data(0, Qt.UserRole + 1)))
  121. self.__render_items(True)
  122. def __render_items(self, is_clear: bool):
  123. if is_clear:
  124. widgets.allTreeWidget.clear()
  125. widgets.qureyTreeWidget.clear()
  126. widgets.allTreeWidget.setColumnCount(1)
  127. widgets.allTreeWidget.setHeaderHidden(True)
  128. widgets.qureyTreeWidget.setColumnCount(1)
  129. widgets.qureyTreeWidget.setHeaderHidden(True)
  130. if self.data.items is not None:
  131. # 转为字典
  132. mapping: dict[any, TreeWidgetItem] = dict(zip([i.id for i in self.data.items], self.data.items))
  133. # 树容器
  134. treeWidgetItems: list[QTreeWidgetItem] = []
  135. for d in self.data.items:
  136. # 如果找不到父级项,则是根节点
  137. parent: TreeWidgetItem = mapping.get(d.parent_id)
  138. if parent is None:
  139. treeWidgetItems.append(d.treeWidgetItem)
  140. else:
  141. parent.treeWidgetItem.addChild(d.treeWidgetItem)
  142. # 挂载到树上
  143. widgets.allTreeWidget.insertTopLevelItems(0, treeWidgetItems)
  144. #查询
  145. class ElTree1(QWidget):
  146. """
  147. Control
  148. """
  149. itemClicked: Signal = Signal(object)
  150. itemDoubleClicked: Signal = Signal(object)
  151. def __init__(self, treeData: ElTreeData, parent=None):
  152. super(ElTree1, self).__init__(parent=parent)
  153. self.data = treeData
  154. # 将按钮的点击信号绑定到当前类的点击信号
  155. widgets.qureyTreeWidget.itemClicked.connect(lambda item: self.itemClicked.emit(item.data(0, Qt.UserRole + 1)))
  156. widgets.qureyTreeWidget.itemDoubleClicked.connect(lambda item: self.itemDoubleClicked.emit(item.data(0, Qt.UserRole + 1)))
  157. self.__render_items(True)
  158. def __render_items(self, is_clear: bool):
  159. if is_clear:
  160. widgets.qureyTreeWidget.clear()
  161. widgets.qureyTreeWidget.setColumnCount(1)
  162. widgets.qureyTreeWidget.setHeaderHidden(True)
  163. if self.data.items is not None:
  164. # 转为字典
  165. mapping: dict[any, TreeWidgetItem] = dict(zip([i.id for i in self.data.items], self.data.items))
  166. # 树容器
  167. treeWidgetItems: list[QTreeWidgetItem] = []
  168. for d in self.data.items:
  169. # 如果找不到父级项,则是根节点
  170. parent: TreeWidgetItem = mapping.get(d.parent_id)
  171. if parent is None:
  172. treeWidgetItems.append(d.treeWidgetItem)
  173. else:
  174. parent.treeWidgetItem.addChild(d.treeWidgetItem)
  175. # 挂载到树上
  176. widgets.qureyTreeWidget.insertTopLevelItems(0, treeWidgetItems)
  177. class MainWindow(QMainWindow):
  178. def __init__(self):
  179. QMainWindow.__init__(self)
  180. # super().__init__()
  181. # SET AS GLOBAL WIDGETS
  182. # ///////////////////////////////////////////////////////////////
  183. self.ui = Ui_MainWindow()
  184. self.ui.setupUi(self)
  185. # self.comboBox_2 = QComboBox(self)
  186. # ...此处为省略代码...
  187. global widgets
  188. widgets = self.ui
  189. # 是否使用系统自带标题栏 True是不使用,False使用
  190. # ///////////////////////////////////////////////////////////////
  191. Settings.ENABLE_CUSTOM_TITLE_BAR = True
  192. # APP名称
  193. # ///////////////////////////////////////////////////////////////
  194. title = "控制网复测平面基准归算程序"
  195. description = "控制网复测平面基准归算程序"
  196. # APPLY TEXTS
  197. self.setWindowTitle(title)
  198. widgets.titleRightInfo.setText(description)
  199. # TOGGLE MENU
  200. # ///////////////////////////////////////////////////////////////
  201. widgets.toggleButton.clicked.connect(lambda: UIFunctions.toggleMenu(self, True))
  202. # SET UI DEFINITIONS
  203. # ///////////////////////////////////////////////////////////////
  204. UIFunctions.uiDefinitions(self)
  205. # QTableWidget PARAMETERS
  206. # ///////////////////////////////////////////////////////////////
  207. # widgets.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
  208. # 点击事件
  209. # ///////////////////////////////////////////////////////////////
  210. # 左边菜单
  211. # 首页
  212. widgets.btn_home.clicked.connect(self.buttonClick)
  213. # 输入表格
  214. widgets.btn_widgets.clicked.connect(self.buttonClick)
  215. # 成果预览
  216. widgets.btn_new.clicked.connect(self.buttonClick)
  217. # 数据一览
  218. widgets.btn_data.clicked.connect(self.buttonClick)
  219. # 皮肤切换
  220. widgets.btn_message.clicked.connect(self.buttonClick)
  221. # 打开上传文件夹
  222. widgets.upload.clicked.connect(self.buttonClick)
  223. # 拓展左侧栏
  224. # def openCloseLeftBox():
  225. # UIFunctions.toggleLeftBox(self, True)
  226. # widgets.toggleLeftBox.clicked.connect(openCloseLeftBox)
  227. # widgets.extraCloseColumnBtn.clicked.connect(openCloseLeftBox)
  228. # EXTRA RIGHT BOX
  229. def openCloseRightBox():
  230. UIFunctions.toggleRightBox(self, True)
  231. widgets.settingsTopBtn.clicked.connect(openCloseRightBox)
  232. # 展示APP
  233. # ///////////////////////////////////////////////////////////////
  234. self.show()
  235. # 设置主题
  236. # ///////////////////////////////////////////////////////////////
  237. if getattr(sys, 'frozen', False):
  238. absPath = os.path.dirname(os.path.abspath(sys.executable))
  239. elif __file__:
  240. absPath = os.path.dirname(os.path.abspath(__file__))
  241. useCustomTheme = True
  242. self.useCustomTheme = useCustomTheme
  243. self.absPath = absPath
  244. # themeFile = r"Front\themes\py_dracula_light.qss"
  245. themeFile = os.path.abspath(os.path.join(self.absPath, "themes/py_dracula_light.qss"))
  246. # 设置主题和HACKS
  247. if useCustomTheme:
  248. # LOAD AND APPLY STYLE
  249. UIFunctions.theme(self, themeFile, True)
  250. # SET HACKS
  251. AppFunctions.setThemeHack(self)
  252. # 设置主页和选择菜单
  253. # ///////////////////////////////////////////////////////////////
  254. widgets.stackedWidget.setCurrentWidget(widgets.home)
  255. widgets.btn_home.setStyleSheet(UIFunctions.selectMenu(widgets.btn_home.styleSheet()))
  256. #初始化树状数据库
  257. tree_button = self.sql_init()
  258. tree_button.itemClicked.connect(self.computeClick)
  259. tree_button.itemDoubleClicked.connect(self.computeClick)
  260. self.bind()
  261. #绑定组件
  262. def bind(self):
  263. # 计算
  264. # widgets.compute.clicked.connect(self.computeClick)
  265. widgets.search.clicked.connect(self.searchClick)
  266. #删除tableview
  267. def delete_table_view(table_view):
  268. table_view.setParent(None)
  269. table_view.deleteLater()
  270. #默认第一个参数是self,所以使用时只有一个参数
  271. #稳定性成果表
  272. def Arrange_Data(self,list1):
  273. #最终return的
  274. list2 = []
  275. #点号部分
  276. nlist = []
  277. for data1 in list1:
  278. #点名
  279. #存每一行的数据
  280. resultlist = []
  281. pn = data1[0].decode('utf-8')
  282. resultlist.append(pn)
  283. nlist.append(pn)
  284. resultlist.append(data1[1])
  285. resultlist.append(data1[2])
  286. resultlist.append(data1[3])
  287. resultlist.append(data1[4])
  288. resultlist.append(data1[5])
  289. resultlist.append(data1[6])
  290. resultlist.append(data1[7])
  291. resultlist.append(data1[8])
  292. resultlist.append(data1[9])
  293. resultlist.append(data1[10])
  294. resultlist.append(data1[11])
  295. #判定1
  296. an1 = data1[12].decode('utf-8')
  297. resultlist.append(an1)
  298. resultlist.append(data1[13])
  299. resultlist.append(data1[14])
  300. resultlist.append(data1[15])
  301. #判定2
  302. an2 = data1[16].decode('utf-8')
  303. resultlist.append(an2)
  304. list2.append(resultlist)
  305. return nlist,list2
  306. #复测成果表
  307. def Arrange_Data1(self,list1):
  308. #最终return的
  309. list2 = []
  310. #点号部分
  311. nlist = []
  312. for data1 in list1:
  313. #点名
  314. #存每一行的数据
  315. resultlist = []
  316. pn = data1[0].decode('utf-8')
  317. resultlist.append(pn)
  318. nlist.append(pn)
  319. resultlist.append(data1[1])
  320. resultlist.append(data1[2])
  321. resultlist.append(data1[3])
  322. resultlist.append(data1[4])
  323. resultlist.append(data1[5])
  324. resultlist.append(data1[6])
  325. resultlist.append(data1[7])
  326. #判定
  327. an1 = data1[8].decode('utf-8')
  328. resultlist.append(an1)
  329. list2.append(resultlist)
  330. return nlist,list2
  331. #基准归算表
  332. def Arrange_Data2(self,list1):
  333. #最终return的
  334. list2 = []
  335. #点号部分
  336. nlist = []
  337. for data1 in list1:
  338. #点名
  339. #存每一行的数据
  340. resultlist = []
  341. pn = data1[0].decode('utf-8')
  342. resultlist.append(pn)
  343. nlist.append(pn)
  344. resultlist.append(data1[1])
  345. resultlist.append(data1[2])
  346. resultlist.append(data1[3])
  347. resultlist.append(data1[4])
  348. resultlist.append(data1[5])
  349. #判定
  350. an1 = data1[6].decode('utf-8')
  351. resultlist.append(an1)
  352. list2.append(resultlist)
  353. return nlist,list2
  354. #稳定性成果表
  355. def Data_in_Cell(self,list1):
  356. model = QStandardItemModel()
  357. xx = 0
  358. while xx < len(list1):
  359. data1 = list1[xx]
  360. #点号
  361. cell1 = str(data1[0])
  362. item = QStandardItem(cell1)
  363. model.setItem(xx, 0, item)
  364. #首期
  365. cell1 = str(round(data1[1],4))
  366. item = QStandardItem(cell1)
  367. model.setItem(xx, 1, item)
  368. cell1 = str(round(data1[2],4))
  369. item = QStandardItem(cell1)
  370. model.setItem(xx, 2, item)
  371. #上期
  372. cell1 = str(round(data1[3],4))
  373. item = QStandardItem(cell1)
  374. model.setItem(xx, 3, item)
  375. cell1 = str(round(data1[4],4))
  376. item = QStandardItem(cell1)
  377. model.setItem(xx, 4, item)
  378. #权
  379. cell1 = str(int(data1[5]))
  380. item = QStandardItem(cell1)
  381. model.setItem(xx, 5, item)
  382. #本期
  383. cell1 = str(round(data1[6],4))
  384. item = QStandardItem(cell1)
  385. model.setItem(xx, 6, item)
  386. cell1 = str(round(data1[7],4))
  387. item = QStandardItem(cell1)
  388. model.setItem(xx, 7, item)
  389. #权
  390. cell1 = str(int(data1[8]))
  391. item = QStandardItem(cell1)
  392. model.setItem(xx, 8, item)
  393. #本-首
  394. cell1 = str(round(data1[9],1))
  395. item = QStandardItem(cell1)
  396. model.setItem(xx, 9, item)
  397. cell1 = str(round(data1[10],1))
  398. item = QStandardItem(cell1)
  399. model.setItem(xx, 10, item)
  400. cell1 = str(round(data1[11],1))
  401. item = QStandardItem(cell1)
  402. model.setItem(xx, 11, item)
  403. #判定(如果是稳定则不显示)
  404. cell1 = str(data1[12])
  405. if cell1 == '稳定':
  406. cell1 = ''
  407. item = QStandardItem(cell1)
  408. model.setItem(xx, 12, item)
  409. #本-上
  410. cell1 = str(round(data1[13],1))
  411. item = QStandardItem(cell1)
  412. model.setItem(xx, 13, item)
  413. cell1 = str(round(data1[14],1))
  414. item = QStandardItem(cell1)
  415. model.setItem(xx, 14, item)
  416. cell1 = str(round(data1[15],1))
  417. item = QStandardItem(cell1)
  418. model.setItem(xx, 15, item)
  419. #判定
  420. cell1 = str(data1[16])
  421. if cell1 == '稳定':
  422. cell1 = ''
  423. item = QStandardItem(cell1)
  424. model.setItem(xx, 16, item)
  425. xx = xx + 1
  426. return model
  427. #复测成果表
  428. def Data_in_Cell1(self,list1):
  429. model = QStandardItemModel()
  430. xx = 0
  431. while xx < len(list1):
  432. data1 = list1[xx]
  433. #点号
  434. cell1 = str(data1[0])
  435. item = QStandardItem(cell1)
  436. model.setItem(xx, 0, item)
  437. #上期
  438. cell1 = str(round(data1[1],4))
  439. item = QStandardItem(cell1)
  440. model.setItem(xx, 1, item)
  441. cell1 = str(round(data1[2],4))
  442. item = QStandardItem(cell1)
  443. model.setItem(xx, 2, item)
  444. #本期
  445. cell1 = str(round(data1[3],4))
  446. item = QStandardItem(cell1)
  447. model.setItem(xx, 3, item)
  448. cell1 = str(round(data1[4],4))
  449. item = QStandardItem(cell1)
  450. model.setItem(xx, 4, item)
  451. #上-本
  452. cell1 = str(round(data1[5],1))
  453. item = QStandardItem(cell1)
  454. model.setItem(xx, 5, item)
  455. cell1 = str(round(data1[6],1))
  456. item = QStandardItem(cell1)
  457. model.setItem(xx, 6, item)
  458. cell1 = str(round(data1[7],1))
  459. item = QStandardItem(cell1)
  460. model.setItem(xx, 7, item)
  461. #判定(如果是稳定则不显示)
  462. cell1 = str(data1[8])
  463. if cell1 == '稳定':
  464. cell1 = ''
  465. item = QStandardItem(cell1)
  466. model.setItem(xx, 8, item)
  467. xx = xx + 1
  468. return model
  469. #基准归算表
  470. def Data_in_Cell2(self,list1):
  471. model = QStandardItemModel()
  472. xx = 0
  473. while xx < len(list1):
  474. data1 = list1[xx]
  475. #点号
  476. cell1 = str(data1[0])
  477. item = QStandardItem(cell1)
  478. model.setItem(xx, 0, item)
  479. #计算
  480. cell1 = str(round(data1[1],4))
  481. item = QStandardItem(cell1)
  482. model.setItem(xx, 1, item)
  483. cell1 = str(round(data1[2],4))
  484. item = QStandardItem(cell1)
  485. model.setItem(xx, 2, item)
  486. #上-计
  487. cell1 = str(round(data1[3],1))
  488. item = QStandardItem(cell1)
  489. model.setItem(xx, 3, item)
  490. cell1 = str(round(data1[4],1))
  491. item = QStandardItem(cell1)
  492. model.setItem(xx, 4, item)
  493. cell1 = str(round(data1[5],1))
  494. item = QStandardItem(cell1)
  495. model.setItem(xx, 5, item)
  496. #判定(如果是稳定则不显示)
  497. cell1 = str(data1[6])
  498. if cell1 == '稳定':
  499. cell1 = ''
  500. item = QStandardItem(cell1)
  501. model.setItem(xx, 6, item)
  502. xx = xx + 1
  503. return model
  504. #设一个全局变量,存数据库中所有的包含内容(数据库-三种方法-表)
  505. dblist = []
  506. #初始化数据一览(数据库全展示)
  507. def sql_init(self):
  508. #初始化全部数据库
  509. # inpath = r'D:\4work_now\20240819GS\20241211\SQL'
  510. inpath = os.path.abspath('../SQL')
  511. #读取所有的数据库名
  512. sqlitem = []
  513. id = 1
  514. for filename in os.listdir(inpath):
  515. #数据库
  516. dbname = filename.split('.',-1)[0]
  517. dbpath = os.path.join(inpath,filename)
  518. sqlitem.append(TreeWidgetItem(id,0,dbname,icon=QIcon(os.path.abspath(os.path.join(self.absPath, "images/icons/cil-clone.png")))))
  519. pid = id
  520. id = id + 1
  521. #三种方法
  522. sqlitem.append(TreeWidgetItem(id, pid, '水准测段高差稳定计算', icon=QIcon(os.path.join(self.absPath, "images/icons/cil-description.png"))))
  523. gcid = id
  524. id = id + 1
  525. sqlitem.append(TreeWidgetItem(id, pid, '控制网复测平面基准计算', icon=QIcon(os.path.join(self.absPath, "images/icons/cil-description.png"))))
  526. gsid = id
  527. id = id + 1
  528. sqlitem.append(TreeWidgetItem(id, pid, '平面控制网稳定性计算', icon=QIcon(os.path.join(self.absPath, "images/icons/cil-description.png"))))
  529. wdid = id
  530. id = id + 1
  531. #读取所有的表名(三种方式往下)
  532. db1 = sqlite3.connect(dbpath)
  533. #获取游标
  534. cursor1 = db1.cursor()
  535. sqlstr1 = 'SELECT TableName FROM GC_Input_Param;'
  536. cursor1.execute(sqlstr1)
  537. result1 = cursor1.fetchall()
  538. for re1 in result1:
  539. str1 = re1[0].decode('utf-8')
  540. list1 = []
  541. list1.append(dbname)
  542. list1.append('水准测段高差稳定计算')
  543. list1.append(str1)
  544. self.dblist.append(list1)
  545. sqlitem.append(TreeWidgetItem(id, gcid, str1, icon=QIcon(
  546. os.path.join(self.absPath, "images/icons/cil-file.png")),extend={'listData': list1}))
  547. id = id + 1
  548. sqlstr2 = 'SELECT TableName FROM GS_Input_Param;'
  549. cursor1.execute(sqlstr2)
  550. result2 = cursor1.fetchall()
  551. for re2 in result2:
  552. str2 = re2[0].decode('utf-8')
  553. list2 = []
  554. list2.append(dbname)
  555. list2.append('控制网复测平面基准计算')
  556. list2.append(str2)
  557. self.dblist.append(list2)
  558. sqlitem.append(TreeWidgetItem(id, gsid, str2, icon=QIcon(os.path.join(self.absPath, "images/icons/cil-file.png")),extend={'listData': list2}))
  559. id = id + 1
  560. sqlstr3 = 'SELECT TableName FROM WD_Input_Param;'
  561. cursor1.execute(sqlstr3)
  562. result3 = cursor1.fetchall()
  563. for re3 in result3:
  564. str3 = re3[0].decode('utf-8')
  565. list3 = []
  566. list3.append(dbname)
  567. list3.append('平面控制网稳定性计算')
  568. list3.append(str3)
  569. self.dblist.append(list3)
  570. sqlitem.append(TreeWidgetItem(id, wdid, str3, icon=QIcon(os.path.join(self.absPath, "images/icons/cil-file.png")),extend={'listData': list3}))
  571. id = id + 1
  572. button = ElTree(ElTreeData(sqlitem))
  573. return button
  574. #关键词查询
  575. def searchClick(self):
  576. # GET BUTTON CLICKED
  577. btn = self.sender()
  578. btnName = btn.objectName()
  579. #获取文本
  580. text1 = self.ui.lineEdit_2.text()
  581. #符合的list
  582. fhlist = []
  583. #查询(待优化)
  584. for list1 in self.dblist:
  585. for li in list1:
  586. if text1 in li:
  587. fhlist.append(list1)
  588. break
  589. #更新item值
  590. sqlitem = []
  591. #前两层是否一致
  592. str1 = ''
  593. str2 = ''
  594. id = 1
  595. pid = 0
  596. fid = 0
  597. zdy = []
  598. for list2 in fhlist:
  599. dbname = list2[0]
  600. if dbname != str1:
  601. str1 = dbname
  602. pid = id
  603. str2 = ''
  604. sqlitem.append(TreeWidgetItem(id, 0, dbname, icon=QIcon(
  605. os.path.join(self.absPath, "images/icons/cil-clone.png"))))
  606. zdy1 = []
  607. zdy1.append(id)
  608. zdy1.append(0)
  609. zdy1.append(dbname)
  610. zdy.append(zdy1)
  611. id = id + 1
  612. mename = list2[1]
  613. if mename != str2:
  614. str2 = mename
  615. fid = id
  616. sqlitem.append(TreeWidgetItem(id, pid, mename, icon=QIcon(
  617. os.path.join(self.absPath, "images/icons/cil-description.png"))))
  618. zdy1 = []
  619. zdy1.append(id)
  620. zdy1.append(pid)
  621. zdy1.append(mename)
  622. zdy.append(zdy1)
  623. id = id + 1
  624. sqlitem.append(TreeWidgetItem(id, fid, list2[2], icon=QIcon(
  625. os.path.join(self.absPath, "images/icons/cil-file.png")), extend={'listData': list2}))
  626. zdy1 = []
  627. zdy1.append(id)
  628. zdy1.append(fid)
  629. zdy1.append(list2[2])
  630. zdy.append(zdy1)
  631. id = id + 1
  632. search_button = ElTree1(ElTreeData(sqlitem))
  633. search_button.itemClicked.connect(self.computeClick)
  634. search_button.itemDoubleClicked.connect(self.computeClick)
  635. #直接这个基础上改点选输出表格(未改)
  636. def computeClick(self):
  637. # GET BUTTON CLICKED
  638. btn = self.sender()
  639. btnName = btn.objectName()
  640. #判定是否获取的是根节点
  641. pd = 1
  642. select_item = self.ui.qureyTreeWidget.currentItem()
  643. #获取点击的item的text和它对应的上两个节点
  644. str1 = select_item.text(0)
  645. try:
  646. pa_item = select_item.parent()
  647. current_text = pa_item.text(0)
  648. z_item = pa_item.parent()
  649. str3 = z_item.text(0)
  650. except:
  651. pd = -1
  652. if current_text == '':
  653. pd = -1
  654. if str3 == '':
  655. pd = -1
  656. if pd == -1:
  657. pass
  658. else:
  659. #数据库目录
  660. inpath= os.path.abspath('../SQL')
  661. file_path= inpath + '/'+str3
  662. # UIFunctions.compute_show_process_excel_file(self, file_path)
  663. # #转换下
  664. # excelname = os.path.basename(file_path)
  665. # utf_en = excelname.encode('utf-8')
  666. # # file_path = file_path
  667. # if current_text == "水准测段高差稳定计算":
  668. # #只显示一个tab
  669. # self.ui.tabWidget.setTabVisible(0,True)
  670. # self.ui.tabWidget.setTabVisible(1,False)
  671. # self.ui.tabWidget.setTabVisible(2,False)
  672. # #重新设置文字名称
  673. # self.ui.tabWidget.setTabText(0,'测段高差计算表')
  674. #
  675. # # 计算结束自动跳转结果页面,并保留查询内容,以便输出
  676. # widgets.stackedWidget.setCurrentWidget(widgets.new_page) # SET PAGE
  677. # UIFunctions.resetStyle(self, btnName) # RESET ANOTHERS BUTTONS SELECTED
  678. # btn.setStyleSheet(UIFunctions.selectMenu(btn.styleSheet())) # SELECT MENU
  679. # elif current_text == "控制网复测平面基准计算":
  680. # #就用已有的选项卡
  681. # self.ui.tabWidget.setTabVisible(0,True)
  682. # self.ui.tabWidget.setTabVisible(1,True)
  683. # self.ui.tabWidget.setTabVisible(2,True)
  684. # #重新设置文字名称
  685. # self.ui.tabWidget.setTabText(0,'复测成果表')
  686. # self.ui.tabWidget.setTabText(1,'基准归算模型')
  687. # self.ui.tabWidget.setTabText(2,'复测基准归算表')
  688. #
  689. # #链接数据库并显示
  690. # # 连接到数据库
  691. # #将结果输出到数据库
  692. # db1 = sqlite3.connect(db_path)
  693. # #获取游标
  694. # cursor1 = db1.cursor()
  695. # #查询表内符合的所有数据(分成两个结果分别显示)
  696. # #复测成果表
  697. # sqlstr1 = 'select PointName,Last_X,Last_Y,Result_X,Result_Y,Last_ResultX,Last_ResultY,Last_ResultP,Dis_Ass from GS_Result_Point WHERE TableName = ?'
  698. # cursor1.execute(sqlstr1,(utf_en,))
  699. # #获取结果集
  700. # result1 = cursor1.fetchall()
  701. # #基准归算表
  702. # sqlstr11 = 'select PointName,Cal_X,Cal_Y,Last_CalX,Last_CalY,Last_CalP,Dis_Ass from GS_Result_Point WHERE TableName = ?'
  703. # cursor1.execute(sqlstr11,(utf_en,))
  704. # #获取结果集
  705. # result2 = cursor1.fetchall()
  706. # #对结果集进行处理,把汉字转换过来,添加表头部分
  707. # nlist1,plist1 = self.Arrange_Data1(result1)
  708. # nlist2,plist2 = self.Arrange_Data2(result2)
  709. # # 创建一个数据模型(复测成果表)
  710. # self.model1 = QStandardItemModel()
  711. # #把数据放进去
  712. # model1 = self.Data_in_Cell1(plist1)
  713. # model2 = self.Data_in_Cell2(plist2)
  714. # #设置表头
  715. # model1.setHorizontalHeaderLabels(['点名', '前期X','前期Y','本期X', '本期Y','前期-本期X','前期-本期Y','前期-本期P','位移判定'])
  716. # model1.setVerticalHeaderLabels(nlist1)
  717. # #QTableView并将数据模型与之关联
  718. # self.ui.resultTableView.setModel(model1)
  719. # self.ui.resultTableView.show()
  720. # #设置表头
  721. # model2.setHorizontalHeaderLabels(['点名', '基准归算X','基准归算Y','前期-归算X','前期-归算Y','前期-归算P','位移判定'])
  722. # model2.setVerticalHeaderLabels(nlist2)
  723. # #QTableView并将数据模型与之关联
  724. # self.ui.reconTableView.setModel(model2)
  725. # self.ui.reconTableView.show()
  726. #
  727. # #富文本的html
  728. # sqlstr2 = 'select Last_ResultName,New_ResultName,Formula_X1,Formula_X2,Formula_X3,Formula_Y1,Formula_Y2,Formula_Y3 from GS_Trans_Param WHERE TableName = ?'
  729. # cursor1.execute(sqlstr2,(utf_en,))
  730. # #获取结果集
  731. # result1 = cursor1.fetchall()
  732. # str1 = result1[0][0].decode('utf-8')
  733. # str2 = result1[0][1].decode('utf-8')
  734. # n1 = result1[0][2]
  735. # n2 = result1[0][3]
  736. # n3 = result1[0][4]
  737. # n4 = result1[0][5]
  738. # n5 = result1[0][6]
  739. # n6 = result1[0][7]
  740. # str0 = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
  741. # <html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
  742. # p, li { white-space: pre-wrap; }
  743. # hr { height: 1px; border-width: 0; }
  744. # li.unchecked::marker { content: "\2610"; }
  745. # li.checked::marker { content: "\2612"; }
  746. # </style></head><body style=" font-family:'Microsoft YaHei UI'; font-size:9pt; font-weight:400; font-style:normal;">
  747. # <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; color:#000000;">"""+str2+"""--"""+str1+"""</span><span style=" font-size:14pt;">已知系统转换公式:</span></p>
  748. # <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; font-weight:700;">X</span><span style=" font-size:14pt;">=(</span><span style=" font-size:14pt; color:#aa0000;">"""+str(n1)+"""</span><span style=" font-size:14pt;">)</span><span style=" font-size:14pt; font-weight:700;">x</span><span style=" font-size:14pt;">+(</span><span style=" font-size:14pt; color:#00aa00;">"""+str(n2)+"""</span><span style=" font-size:14pt;">)</span><span style=" font-size:14pt; font-weight:700;">y</span><span style=" font-size:14pt;">+(</span><span style=" font-size:14pt; color:#00007f;">"""+str(n3)+"""</span><span style=" font-size:14pt;">)</span></p>
  749. # <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; font-weight:700;">Y</span><span style=" font-size:14pt;">=(</span><span style=" font-size:14pt; color:#aa0000;">"""+str(n4)+"""</span><span style=" font-size:14pt;">)</span><span style=" font-size:14pt; font-weight:700;">x</span><span style=" font-size:14pt;">+(</span><span style=" font-size:14pt; color:#00aa00;">"""+str(n5)+"""</span><span style=" font-size:14pt;">)</span><span style=" font-size:14pt; font-weight:700;">y</span><span style=" font-size:14pt;">+(</span><span style=" font-size:14pt; color:#00007f;">"""+str(n6)+"""</span><span style=" font-size:14pt;">)</span></p>
  750. # <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt;">式中:</span><span style=" font-size:14pt; font-weight:700; color:#000000;">x、y</span><span style=" font-size:14pt;">为</span><span style=" font-size:14pt; color:#000000;">"""+str2+"""</span><span style=" font-size:14pt;">坐标;</span></p>
  751. # <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt;"> </span><span style=" font-size:14pt; font-weight:700;">X、Y</span><span style=" font-size:14pt;">为"""+str1+"""已知系统的"""+str2+"""归算坐标。</span></p></body></html>"""
  752. # self.ui.printTableView.setHtml(str0)
  753. #
  754. # # 计算结束自动跳转结果页面,并保留查询内容,以便输出
  755. # widgets.stackedWidget.setCurrentWidget(widgets.new_page) # SET PAGE
  756. # UIFunctions.resetStyle(self, btnName) # RESET ANOTHERS BUTTONS SELECTED
  757. # btn.setStyleSheet(UIFunctions.selectMenu(btn.styleSheet())) # SELECT MENU
  758. # # GS.main_function(file_path, db_path)
  759. # # 添加控制网执行代码
  760. # elif current_text=="平面控制网稳定性计算":
  761. # #只显示头两个tab
  762. # self.ui.tabWidget.setTabVisible(0,True)
  763. # self.ui.tabWidget.setTabVisible(1,True)
  764. # self.ui.tabWidget.setTabVisible(2,False)
  765. # #重新设置文字名称
  766. # self.ui.tabWidget.setTabText(0,'稳定性分析成果表')
  767. # self.ui.tabWidget.setTabText(1,'自由网成果归算模型')
  768. # #链接数据库并显示
  769. # # 连接到数据库
  770. # #将结果输出到数据库
  771. # db1 = sqlite3.connect(db_path)
  772. # #获取游标
  773. # cursor1 = db1.cursor()
  774. # #查询表内符合的所有数据
  775. # sqlstr1 = 'select PointName,First_X,First_Y,Last_X,Last_Y,Last_Wight,Result_X,Result_Y,New_Wight,New_FirstX,New_FirstY,New_FirstP,NFDis_Ass,New_LastX,New_LastY,New_LastP,NLDis_Ass from WD_Result_Point WHERE TableName = ?'
  776. # cursor1.execute(sqlstr1,(utf_en,))
  777. # #获取结果集
  778. # result = cursor1.fetchall()
  779. # #对结果集进行处理,把汉字转换过来,添加表头部分
  780. # nlist,plist = self.Arrange_Data(result)
  781. # # 创建一个数据模型
  782. # self.model = QStandardItemModel()
  783. # #把数据放进去
  784. # model1 = self.Data_in_Cell(plist)
  785. # #设置表头
  786. # model1.setHorizontalHeaderLabels(['点名', '首期X','首期Y','上期X', '上期Y','权','本期X','本期Y','权','本期-首期X','本期-首期Y','本期-首期P','位移判定', '本期-上期X','本期-上期Y','本期-上期P','位移判定'])
  787. # model1.setVerticalHeaderLabels(nlist)
  788. # #QTableView并将数据模型与之关联
  789. # self.ui.resultTableView.setModel(model1)
  790. # self.ui.resultTableView.show()
  791. #
  792. # #富文本的html
  793. # sqlstr2 = 'select Last_ResultName,New_ResultName,Formula_X1,Formula_X2,Formula_X3,Formula_Y1,Formula_Y2,Formula_Y3 from WD_Result_Param WHERE TableName = ?'
  794. # cursor1.execute(sqlstr2,(utf_en,))
  795. # #获取结果集
  796. # result1 = cursor1.fetchall()
  797. # str1 = result1[0][0].decode('utf-8')
  798. # str2 = result1[0][1].decode('utf-8')
  799. # n1 = result1[0][2]
  800. # n2 = result1[0][3]
  801. # n3 = result1[0][4]
  802. # n4 = result1[0][5]
  803. # n5 = result1[0][6]
  804. # n6 = result1[0][7]
  805. # str0 = """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
  806. # <html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css">
  807. # p, li { white-space: pre-wrap; }
  808. # hr { height: 1px; border-width: 0; }
  809. # li.unchecked::marker { content: "\2610"; }
  810. # li.checked::marker { content: "\2612"; }
  811. # </style></head><body style=" font-family:'Microsoft YaHei UI'; font-size:9pt; font-weight:400; font-style:normal;">
  812. # <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; color:#000000;">"""+str2+"""--"""+str1+"""</span><span style=" font-size:14pt;">已知系统转换公式:</span></p>
  813. # <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; font-weight:700;">X</span><span style=" font-size:14pt;">=(</span><span style=" font-size:14pt; color:#aa0000;">"""+str(n1)+"""</span><span style=" font-size:14pt;">)</span><span style=" font-size:14pt; font-weight:700;">x</span><span style=" font-size:14pt;">+(</span><span style=" font-size:14pt; color:#00aa00;">"""+str(n2)+"""</span><span style=" font-size:14pt;">)</span><span style=" font-size:14pt; font-weight:700;">y</span><span style=" font-size:14pt;">+(</span><span style=" font-size:14pt; color:#00007f;">"""+str(n3)+"""</span><span style=" font-size:14pt;">)</span></p>
  814. # <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt; font-weight:700;">Y</span><span style=" font-size:14pt;">=(</span><span style=" font-size:14pt; color:#aa0000;">"""+str(n4)+"""</span><span style=" font-size:14pt;">)</span><span style=" font-size:14pt; font-weight:700;">x</span><span style=" font-size:14pt;">+(</span><span style=" font-size:14pt; color:#00aa00;">"""+str(n5)+"""</span><span style=" font-size:14pt;">)</span><span style=" font-size:14pt; font-weight:700;">y</span><span style=" font-size:14pt;">+(</span><span style=" font-size:14pt; color:#00007f;">"""+str(n6)+"""</span><span style=" font-size:14pt;">)</span></p>
  815. # <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt;">式中:</span><span style=" font-size:14pt; font-weight:700; color:#000000;">x、y</span><span style=" font-size:14pt;">为</span><span style=" font-size:14pt; color:#000000;">"""+str2+"""</span><span style=" font-size:14pt;">坐标;</span></p>
  816. # <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:14pt;"> </span><span style=" font-size:14pt; font-weight:700;">X、Y</span><span style=" font-size:14pt;">为"""+str1+"""已知系统的"""+str2+"""归算坐标。</span></p></body></html>"""
  817. # self.ui.printTableView.setHtml(str0)
  818. #
  819. # #----------------------------------------------------------
  820. # # 计算结束自动跳转结果页面,并保留查询内容,以便输出
  821. # widgets.stackedWidget.setCurrentWidget(widgets.new_page) # SET PAGE
  822. # UIFunctions.resetStyle(self, btnName) # RESET ANOTHERS BUTTONS SELECTED
  823. # btn.setStyleSheet(UIFunctions.selectMenu(btn.styleSheet())) # SELECT MENU
  824. # 点击事件
  825. # 在这里添加点击事件的方法
  826. # ///////////////////////////////////////////////////////////////
  827. def buttonClick(self):
  828. # GET BUTTON CLICKED
  829. btn = self.sender()
  830. btnName = btn.objectName()
  831. # 首页
  832. if btnName == "btn_home":
  833. widgets.stackedWidget.setCurrentWidget(widgets.home)
  834. UIFunctions.resetStyle(self, btnName)
  835. btn.setStyleSheet(UIFunctions.selectMenu(btn.styleSheet()))
  836. # 输入表格
  837. if btnName == "btn_widgets":
  838. widgets.stackedWidget.setCurrentWidget(widgets.widgets)
  839. UIFunctions.resetStyle(self, btnName)
  840. btn.setStyleSheet(UIFunctions.selectMenu(btn.styleSheet()))
  841. # 成果预览
  842. if btnName == "btn_new":
  843. widgets.stackedWidget.setCurrentWidget(widgets.new_page) # SET PAGE
  844. UIFunctions.resetStyle(self, btnName) # RESET ANOTHERS BUTTONS SELECTED
  845. btn.setStyleSheet(UIFunctions.selectMenu(btn.styleSheet())) # SELECT MENU
  846. # 数据一览
  847. if btnName == "btn_data":
  848. widgets.stackedWidget.setCurrentWidget(widgets.datainfo) # SET PAGE
  849. UIFunctions.resetStyle(self, btnName) # RESET ANOTHERS BUTTONS SELECTED
  850. btn.setStyleSheet(UIFunctions.selectMenu(btn.styleSheet())) # SELECT MENU
  851. # 皮肤切换
  852. if btnName == "btn_message":
  853. if self.useCustomTheme:
  854. themeFile = os.path.abspath(os.path.join(self.absPath, "themes/py_dracula_dark.qss"))
  855. UIFunctions.theme(self, themeFile, True)
  856. # SET HACKS
  857. AppFunctions.setThemeHack(self)
  858. self.useCustomTheme = False
  859. else:
  860. themeFile = os.path.abspath(os.path.join(self.absPath, "themes/py_dracula_light.qss"))
  861. UIFunctions.theme(self, themeFile, True)
  862. # SET HACKS
  863. AppFunctions.setThemeHack(self)
  864. self.useCustomTheme = True
  865. # 文件上传
  866. if btnName == "upload":
  867. global file_path
  868. # options = QFileDialog.Options()
  869. # 使用 QFileDialog 获取文件路径
  870. file_path, _ = QFileDialog.getOpenFileName(
  871. self,
  872. "选择文件",
  873. "",
  874. "表格文件 (*.xls *.xlsx)"
  875. )
  876. if file_path:
  877. # 处理选中的文件
  878. # print(file_path)
  879. UIFunctions.execute_script_based_on_selection(self, file_path)
  880. # messagebox.showinfo("提示",f"文件 '{file_name}' 跳转成功!")
  881. # 输出点击回馈
  882. print(f'Button "{btnName}" pressed!')
  883. # RESIZE EVENTS
  884. # ///////////////////////////////////////////////////////////////
  885. def resizeEvent(self, event):
  886. # Update Size Grips
  887. UIFunctions.resize_grips(self)
  888. # 鼠标点击事件
  889. # ///////////////////////////////////////////////////////////////
  890. def mousePressEvent(self, event):
  891. # SET DRAG POS WINDOW
  892. self.dragPos = event.globalPos()
  893. # 输出鼠标事件
  894. if event.buttons() == Qt.LeftButton:
  895. print('Mouse click: LEFT CLICK')
  896. if event.buttons() == Qt.RightButton:
  897. print('Mouse click: RIGHT CLICK')
  898. if __name__ == "__main__":
  899. app = QApplication(sys.argv)
  900. app.setWindowIcon(QIcon("icon.ico"))
  901. window = MainWindow()
  902. # window.resize(1440, 960) # 高宽
  903. sys.exit(app.exec())