|
@@ -18,6 +18,8 @@ import time
|
18
|
18
|
from PySide6.QtWidgets import QFileDialog, QWidget, QVBoxLayout, QTreeWidget, QApplication, QTreeWidgetItem
|
19
|
19
|
from PySide6.QtCore import Signal, Qt, Slot, QObject
|
20
|
20
|
from PySide6.QtSql import QSqlTableModel, QSqlDatabase
|
|
21
|
+from watchdog.observers import Observer
|
|
22
|
+from watchdog.events import FileSystemEventHandler
|
21
|
23
|
import sqlite3
|
22
|
24
|
from PySide6.QtGui import QIcon
|
23
|
25
|
|
|
@@ -146,6 +148,11 @@ class ElTree(QWidget):
|
146
|
148
|
lambda item: self.itemDoubleClicked.emit(item.data(0, Qt.UserRole + 1)))
|
147
|
149
|
self.__render_items(True)
|
148
|
150
|
|
|
151
|
+ # 设置 QTreeWidget 的 contextMenuPolicy 为 Qt.CustomContextMenu
|
|
152
|
+ widgets.allTreeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
|
|
153
|
+ # 连接 customContextMenuRequested 信号到 contextMenuEvent 方法
|
|
154
|
+ widgets.allTreeWidget.customContextMenuRequested.connect(self.contextMenuEvent)
|
|
155
|
+
|
149
|
156
|
def __render_items(self, is_clear: bool):
|
150
|
157
|
if is_clear:
|
151
|
158
|
widgets.allTreeWidget.clear()
|
|
@@ -170,6 +177,90 @@ class ElTree(QWidget):
|
170
|
177
|
# 挂载到树上
|
171
|
178
|
widgets.allTreeWidget.insertTopLevelItems(0, treeWidgetItems)
|
172
|
179
|
|
|
180
|
+ def contextMenuEvent(self, pos):
|
|
181
|
+ print("contextMenuEvent called") # 调试信息
|
|
182
|
+ # 创建右键菜单
|
|
183
|
+ context_menu = QMenu(self)
|
|
184
|
+ delete_action = QAction("删除", self)
|
|
185
|
+ delete_action.triggered.connect(self.delete_item)
|
|
186
|
+ context_menu.addAction(delete_action)
|
|
187
|
+ context_menu.exec(widgets.allTreeWidget.mapToGlobal(pos))
|
|
188
|
+
|
|
189
|
+ def delete_item(self):
|
|
190
|
+ # 获取当前选中的项目
|
|
191
|
+ selected_items = widgets.allTreeWidget.selectedItems()
|
|
192
|
+ if not selected_items:
|
|
193
|
+ QMessageBox.warning(self, '警告', '请先选择一个项目')
|
|
194
|
+ return
|
|
195
|
+
|
|
196
|
+ item = selected_items[0]
|
|
197
|
+ data = item.data(0, Qt.UserRole + 1)
|
|
198
|
+ if not data:
|
|
199
|
+ QMessageBox.warning(self, '警告', '所选项目没有关联的数据')
|
|
200
|
+ return
|
|
201
|
+
|
|
202
|
+ # 获取数据库路径和表名
|
|
203
|
+ dbname = data['listData'][0]
|
|
204
|
+ tablename = data['listData'][2]
|
|
205
|
+ dbpath = os.path.join(os.path.abspath('../SQL'), f"{dbname}.db")
|
|
206
|
+ print(dbpath)
|
|
207
|
+ print(tablename)
|
|
208
|
+
|
|
209
|
+ # 确保 tablename 是 UTF-8 编码的字符串
|
|
210
|
+ try:
|
|
211
|
+ tablename_utf8 = tablename.encode('utf-8')
|
|
212
|
+ except Exception as e:
|
|
213
|
+ QMessageBox.critical(self, '错误', f'表名编码转换错误: {str(e)}')
|
|
214
|
+ return
|
|
215
|
+ print(tablename_utf8)
|
|
216
|
+ # 获取父节点
|
|
217
|
+ parent_item = item.parent()
|
|
218
|
+ if not parent_item:
|
|
219
|
+ QMessageBox.warning(self, '警告', '所选项目没有父节点')
|
|
220
|
+ return
|
|
221
|
+
|
|
222
|
+ parent_name = parent_item.text(0)
|
|
223
|
+ print(f"Parent Name: {parent_name}")
|
|
224
|
+
|
|
225
|
+ # 确定要删除的表
|
|
226
|
+ tables_to_delete = []
|
|
227
|
+ if parent_name == '水准测段高差稳定计算':
|
|
228
|
+ tables_to_delete = ['GC_Input_Param', 'GC_Input_Point', 'GC_Output_Point']
|
|
229
|
+ elif parent_name == '控制网复测平面基准计算':
|
|
230
|
+ tables_to_delete = ['GS_Input_Param', 'GS_Input_Point', 'GS_Result_Point', 'GS_Trans_Param', 'GS_Trans_Point']
|
|
231
|
+ elif parent_name == '平面控制网稳定性计算':
|
|
232
|
+ tables_to_delete = ['WD_Input_Param', 'WD_Input_Point', 'WD_Result_Param', 'WD_Result_Point']
|
|
233
|
+ else:
|
|
234
|
+ QMessageBox.warning(self, '警告', '未知的父节点')
|
|
235
|
+ return
|
|
236
|
+
|
|
237
|
+ # 确认删除操作
|
|
238
|
+ reply = QMessageBox.question(self, '确认删除', f'确定要删除项目表 {tablename} 吗?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
|
|
239
|
+ if reply == QMessageBox.No:
|
|
240
|
+ return
|
|
241
|
+
|
|
242
|
+ # 清空表
|
|
243
|
+ try:
|
|
244
|
+ conn = sqlite3.connect(dbpath)
|
|
245
|
+ cursor = conn.cursor()
|
|
246
|
+ for table in tables_to_delete:
|
|
247
|
+ cursor.execute(f"DELETE FROM {table} WHERE TableName = ?", (tablename_utf8,))
|
|
248
|
+ conn.commit()
|
|
249
|
+ conn.close()
|
|
250
|
+ QMessageBox.information(self, '成功', f'表 {tablename} 中的数据已从相关表中删除')
|
|
251
|
+
|
|
252
|
+ # 刷新树状图
|
|
253
|
+ self.refresh_tree()
|
|
254
|
+ except Exception as e:
|
|
255
|
+ QMessageBox.critical(self, '错误', f'删除数据时出错: {str(e)}')
|
|
256
|
+ print(e)
|
|
257
|
+
|
|
258
|
+ def refresh_tree(self):
|
|
259
|
+ # 调用 MainWindow 的 refresh_tree 方法
|
|
260
|
+ main_window = QApplication.instance().activeWindow()
|
|
261
|
+ if isinstance(main_window, MainWindow):
|
|
262
|
+ main_window.refresh_tree()
|
|
263
|
+
|
173
|
264
|
|
174
|
265
|
# 查询
|
175
|
266
|
class ElTree1(QWidget):
|
|
@@ -209,6 +300,14 @@ class ElTree1(QWidget):
|
209
|
300
|
# 挂载到树上
|
210
|
301
|
widgets.qureyTreeWidget.insertTopLevelItems(0, treeWidgetItems)
|
211
|
302
|
|
|
303
|
+class DatabaseChangeHandler(FileSystemEventHandler):
|
|
304
|
+ def __init__(self, main_window):
|
|
305
|
+ self.main_window = main_window
|
|
306
|
+
|
|
307
|
+ def on_modified(self, event):
|
|
308
|
+ if event.src_path.endswith('.db'):
|
|
309
|
+ print(f"Database file {event.src_path} has been modified.")
|
|
310
|
+ self.main_window.refresh_tree()
|
212
|
311
|
|
213
|
312
|
class MainWindow(QMainWindow):
|
214
|
313
|
|
|
@@ -223,6 +322,10 @@ class MainWindow(QMainWindow):
|
223
|
322
|
# 连接信号与槽函数,实现点击操作
|
224
|
323
|
self.ui.createFile.clicked.connect(self.on_create_file_clicked)
|
225
|
324
|
self.ui.export_2.clicked.connect(self.on_export_2_clicked)
|
|
325
|
+ # 初始化数据库监控
|
|
326
|
+ self.observer = Observer()
|
|
327
|
+ self.observer.schedule(DatabaseChangeHandler(self), path=os.path.abspath('../SQL'), recursive=False)
|
|
328
|
+ self.observer.start()
|
226
|
329
|
# self.comboBox_2 = QComboBox(self)
|
227
|
330
|
# ...此处为省略代码...
|
228
|
331
|
global widgets
|
|
@@ -318,9 +421,16 @@ class MainWindow(QMainWindow):
|
318
|
421
|
# self.bind()
|
319
|
422
|
|
320
|
423
|
# 初始化树状数据库
|
321
|
|
- tree_button = self.sql_init()
|
322
|
|
- tree_button.itemClicked.connect(self.itembuttonClick)
|
323
|
|
- tree_button.itemDoubleClicked.connect(self.itembuttonClick)
|
|
424
|
+ self.refresh_tree()
|
|
425
|
+
|
|
426
|
+ # tree_button = self.sql_init()
|
|
427
|
+ # tree_button.itemClicked.connect(self.itembuttonClick)
|
|
428
|
+ # tree_button.itemDoubleClicked.connect(self.itembuttonClick)
|
|
429
|
+ def closeEvent(self, event):
|
|
430
|
+ # 停止监控
|
|
431
|
+ self.observer.stop()
|
|
432
|
+ self.observer.join()
|
|
433
|
+ event.accept()
|
324
|
434
|
|
325
|
435
|
# 绑定组件
|
326
|
436
|
def bind(self):
|
|
@@ -438,7 +548,7 @@ class MainWindow(QMainWindow):
|
438
|
548
|
def mousePressEvent(self, event):
|
439
|
549
|
# SET DRAG POS WINDOW
|
440
|
550
|
# self.dragPos = event.globalPos()
|
441
|
|
- self.dragPos = event.globalPosition().toPoint()
|
|
551
|
+ self.dragPos = event.globalPosition().toPoint() # 设置鼠标拖动位置
|
442
|
552
|
|
443
|
553
|
# 输出鼠标事件
|
444
|
554
|
if event.buttons() == Qt.LeftButton:
|
|
@@ -526,6 +636,17 @@ class MainWindow(QMainWindow):
|
526
|
636
|
button = ElTree(ElTreeData(sqlitem))
|
527
|
637
|
return button
|
528
|
638
|
|
|
639
|
+ # 刷新树状图
|
|
640
|
+ def refresh_tree(self):
|
|
641
|
+ # 清空当前的树状图
|
|
642
|
+ widgets.allTreeWidget.clear()
|
|
643
|
+ # 重新初始化树状图
|
|
644
|
+ tree_button = self.sql_init()
|
|
645
|
+ tree_button.itemClicked.connect(self.itembuttonClick)
|
|
646
|
+ tree_button.itemDoubleClicked.connect(self.itembuttonClick)
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
|
529
|
650
|
# 关键词查询
|
530
|
651
|
def searchClick(self):
|
531
|
652
|
# GET BUTTON CLICKED
|