1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018 |
- # ///////////////////////////////////////////////////////////////
- #
- # BY: WANDERSON M.PIMENTA
- # PROJECT MADE WITH: Qt Designer and PySide6
- # V: 1.0.0
- #
- # This project can be used freely for all uses, as long as they maintain the
- # respective credits only in the Python scripts, any information in the visual
- # interface (GUI) can be modified without any implication.
- #
- # There are limitations on Qt licenses if you want to use your products
- # commercially, I recommend reading them on the official website:
- # https://doc.qt.io/qtforpython/licenses.html
- #
- # ///////////////////////////////////////////////////////////////
- import time
-
- from PySide6.QtTest import QTest
- from PySide6.QtWidgets import QFileDialog, QWidget, QVBoxLayout, QTreeWidget, QApplication, QTreeWidgetItem
- from PySide6.QtCore import Signal, Qt, Slot, QObject
- from PySide6.QtSql import QSqlTableModel, QSqlDatabase
- from watchdog.observers import Observer
- from watchdog.events import FileSystemEventHandler
- import sqlite3
- from PySide6.QtGui import QIcon
-
- import sys
- import os
- import platform
-
- import Back.Program_Run.database_operations
- # IMPORT / GUI AND MODULES AND WIDGETS
- # ///////////////////////////////////////////////////////////////
- from modules import *
- from widgets import *
-
- os.environ["QT_FONT_DPI"] = "96" # FIX Problem for High DPI and Scale above 100%
-
- # SET AS GLOBAL WIDGETS
- # ///////////////////////////////////////////////////////////////
- widgets = None
- excelname = ''
-
- # 获取项目根目录
- project_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
- # 将项目根目录添加到 sys.path
- sys.path.append(project_root)
-
-
- # 表格的模型
- class MyTableModel(QAbstractTableModel):
- def __init__(self, data):
- super().__init__()
- self._data = data
-
- # 重新定义行数
- def rowCount(self, parent=QModelIndex()):
- return len(self._data)
-
- # 重新定义列数
- def columnCount(self, parent=QModelIndex()):
- return len(self._data[0]) if self._data else 0
-
- # 重新定义数据
- def data(self, index, role=Qt.DisplayRole):
- if not index.isValid():
- return None
- if role == Qt.DisplayRole:
- return self._data[index.row()][index.column()]
- return None
-
-
- # 数据一览树状
- class TreeWidgetItem:
- def __init__(self, id: any, parent_id: any, name: str, icon: QIcon = None, extend: object = None):
- """
- 菜单数据接口
- :param id: ID
- :param parent_id: 父ID
- :param name: 菜单名称
- :param icon: 图标
- :param extend: 扩展数据
- """
- self.id: any = id
- self.parent_id: any = parent_id
- self.name: str = name
- self.extend: object = extend
- # 实例化
- self.treeWidgetItem = QTreeWidgetItem([self.name])
- # 存储相关数据
- self.treeWidgetItem.setData(0, Qt.UserRole + 1, extend)
- self.treeWidgetItem.setIcon(0, QIcon(':/icons/default.png'))
- if icon is not None:
- self.treeWidgetItem.setIcon(0, icon)
-
-
- class ElTreeData(QObject):
- """
- Data Model
- """
- items_changed: Signal = Signal(str)
- styleSheet_changed: Signal = Signal(str)
-
- def __init__(self, items: list[TreeWidgetItem] = None, styleSheet: str = None):
- super(ElTreeData, self).__init__()
- # 定义数据
- self._items: list[TreeWidgetItem]
- self._styleSheet: str
- # 初始化数据
- self.items = items
- self.styleSheet = styleSheet
-
- @property
- def items(self):
- return self._items
-
- @items.setter
- def items(self, value):
- self._items = value
- # 数据改变时发出信号
- self.items_changed.emit(self.items)
-
- @property
- def styleSheet(self):
- return self._styleSheet
-
- @styleSheet.setter
- def styleSheet(self, value):
- self._styleSheet = value
- # 数据改变时发出信号
- self.styleSheet_changed.emit(self.styleSheet)
-
-
- # 全数据库
- class ElTree(QWidget):
- """
- Control
- """
- itemClicked: Signal = Signal(object)
- itemDoubleClicked: Signal = Signal(object)
-
- def __init__(self, treeData: ElTreeData, parent=None):
- super(ElTree, self).__init__(parent=parent)
-
- self.data = treeData
- # 将按钮的点击信号绑定到当前类的点击信号
- widgets.allTreeWidget.itemClicked.connect(lambda item: self.itemClicked.emit(item.data(0, Qt.UserRole + 1)))
- widgets.allTreeWidget.itemDoubleClicked.connect(
- lambda item: self.itemDoubleClicked.emit(item.data(0, Qt.UserRole + 1)))
- self.__render_items(True)
-
- # 设置 QTreeWidget 的 contextMenuPolicy 为 Qt.CustomContextMenu
- widgets.allTreeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
- # 连接 customContextMenuRequested 信号到 contextMenuEvent 方法
- widgets.allTreeWidget.customContextMenuRequested.connect(self.contextMenuEvent)
-
- def __render_items(self, is_clear: bool):
- if is_clear:
- widgets.allTreeWidget.clear()
- widgets.qureyTreeWidget.clear()
- widgets.allTreeWidget.setColumnCount(1)
- widgets.allTreeWidget.setHeaderHidden(True)
- widgets.qureyTreeWidget.setColumnCount(1)
- widgets.qureyTreeWidget.setHeaderHidden(True)
- if self.data.items is not None:
- # 转为字典
- mapping: dict[any, TreeWidgetItem] = dict(zip([i.id for i in self.data.items], self.data.items))
- # 树容器
- treeWidgetItems: list[QTreeWidgetItem] = []
- for d in self.data.items:
- # 如果找不到父级项,则是根节点
- parent: TreeWidgetItem = mapping.get(d.parent_id)
- if parent is None:
- treeWidgetItems.append(d.treeWidgetItem)
- else:
- parent.treeWidgetItem.addChild(d.treeWidgetItem)
-
- # 挂载到树上
- widgets.allTreeWidget.insertTopLevelItems(0, treeWidgetItems)
-
- def contextMenuEvent(self, pos):
- # 创建右键菜单
- context_menu = QMenu(self)
-
- # 添加删除选项
- delete_action = QAction("删除", self)
- delete_action.triggered.connect(self.delete_item)
- context_menu.addAction(delete_action)
-
- # 添加导出选项
- export_action = QAction("导出", self)
- export_action.triggered.connect(self.export_item)
- context_menu.addAction(export_action)
-
- context_menu.exec(widgets.allTreeWidget.mapToGlobal(pos))
-
- def delete_item(self):
- # 获取当前选中的项目
- selected_items = widgets.allTreeWidget.selectedItems()
- if not selected_items:
- QMessageBox.warning(self, '警告', '请先选择一个项目')
- return
-
- item = selected_items[0]
- data = item.data(0, Qt.UserRole + 1)
- if not data:
- self.warning = QMessageBox.warning(self, '警告', '所选项目没有关联的数据')
- return
-
- # 获取数据库路径和表名
- dbname = data['listData'][0]
- tablename = data['listData'][2]
- dbpath = os.path.join(os.path.abspath('../SQL'), f"{dbname}.db")
-
- # 确保 tablename 是 UTF-8 编码的字符串
- try:
- tablename_utf8 = tablename.encode('utf-8')
- except Exception as e:
- QMessageBox.critical(self, '错误', f'表名编码转换错误: {str(e)}')
- return
- # 获取父节点
- parent_item = item.parent()
- if not parent_item:
- QMessageBox.warning(self, '警告', '所选项目没有父节点')
- return
-
- parent_name = parent_item.text(0)
-
- # 确定要删除的表
- tables_to_delete = []
- if parent_name == '水准测段高差稳定计算':
- tables_to_delete = ['GC_Input_Param', 'GC_Input_Point', 'GC_Output_Point']
- elif parent_name == '控制网复测平面基准计算':
- tables_to_delete = ['GS_Input_Param', 'GS_Input_Point', 'GS_Result_Point', 'GS_Trans_Param',
- 'GS_Trans_Point']
- elif parent_name == '平面控制网稳定性计算':
- tables_to_delete = ['WD_Input_Param', 'WD_Input_Point', 'WD_Result_Param', 'WD_Result_Point']
- else:
- QMessageBox.warning(self, '警告', '未知的父节点')
- return
-
- # 确认删除操作
- reply = QMessageBox.question(self, '确认删除', f'确定要删除项目表 {tablename} 吗?',
- QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
- if reply == QMessageBox.No:
- return
-
- # 清空表
- try:
- conn = sqlite3.connect(dbpath)
- cursor = conn.cursor()
- for table in tables_to_delete:
- cursor.execute(f"DELETE FROM {table} WHERE TableName = ?", (tablename_utf8,))
- conn.commit()
- conn.close()
- QMessageBox.information(self, '成功', f'表 {tablename} 中的数据已从相关表中删除')
-
- # 刷新树状图
- self.refresh_tree()
- except Exception as e:
- QMessageBox.critical(self, '错误', f'删除数据时出错: {str(e)}')
-
- def export_item(self):
- # 获取当前选中的项目
- selected_items = widgets.allTreeWidget.selectedItems()
- if not selected_items:
- QMessageBox.warning(self, '警告', '请先选择一个项目')
- return
-
- item = selected_items[0]
- data = item.data(0, Qt.UserRole + 1)
- if not data:
- QMessageBox.warning(self, '警告', '所选项目没有关联的数据')
- return
-
- # 获取数据库路径和表名
- dbname = data['listData'][0]
- tablename = data['listData'][2]
- tablename_utf8 = tablename.encode('utf-8')
- dbpath = os.path.join(os.path.abspath('../SQL'), f"{dbname}.db")
-
- # 获取父节点
- parent_item = item.parent()
- if not parent_item:
- QMessageBox.warning(self, '警告', '所选项目没有父节点')
- return
-
- parent_name = parent_item.text(0)
-
- # 根据父节点名称确定导出操作
- if parent_name == '水准测段高差稳定计算':
- GCExport.main_function_initial(self, tablename_utf8, dbpath)
- GCExport.main_function_result(self, tablename_utf8, dbpath)
- elif parent_name == '控制网复测平面基准计算':
- GSExport.main_function(self, dbpath, tablename)
- elif parent_name == '平面控制网稳定性计算':
- WDExport.main_function(self, dbpath, tablename)
- else:
- QMessageBox.warning(self, '警告', '未知的父节点')
- return
-
- def refresh_tree(self):
- # 调用 MainWindow 的 refresh_tree 方法
- main_window = QApplication.instance().activeWindow()
- if isinstance(main_window, MainWindow):
- main_window.refresh_tree()
-
-
- # 查询
- # 查询
- class ElTree1(QWidget):
- """
- Control
- """
- itemClicked: Signal = Signal(object)
- itemDoubleClicked: Signal = Signal(object)
-
- def __init__(self, treeData: ElTreeData, parent=None):
- super(ElTree1, self).__init__(parent=parent)
- self.data = treeData
- # 将按钮的点击信号绑定到当前类的点击信号
- widgets.qureyTreeWidget.itemClicked.connect(lambda item: self.itemClicked.emit(item.data(0, Qt.UserRole + 1)))
- widgets.qureyTreeWidget.itemDoubleClicked.connect(
- lambda item: self.itemDoubleClicked.emit(item.data(0, Qt.UserRole + 1)))
- self.__render_items(True)
-
- # 设置 QTreeWidget 的 contextMenuPolicy 为 Qt.CustomContextMenu
- widgets.qureyTreeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
- # 连接 customContextMenuRequested 信号到 contextMenuEvent 方法
- widgets.qureyTreeWidget.customContextMenuRequested.connect(self.contextMenuEvent)
-
- def __render_items(self, is_clear: bool):
- if is_clear:
- widgets.qureyTreeWidget.clear()
- widgets.qureyTreeWidget.setColumnCount(1)
- widgets.qureyTreeWidget.setHeaderHidden(True)
- if self.data.items is not None:
- # 转为字典
- mapping: dict[any, TreeWidgetItem] = dict(zip([i.id for i in self.data.items], self.data.items))
- # 树容器
- treeWidgetItems: list[QTreeWidgetItem] = []
- for d in self.data.items:
- # 如果找不到父级项,则是根节点
- parent: TreeWidgetItem = mapping.get(d.parent_id)
- if parent is None:
- treeWidgetItems.append(d.treeWidgetItem)
- else:
- parent.treeWidgetItem.addChild(d.treeWidgetItem)
-
- # 挂载到树上
- widgets.qureyTreeWidget.insertTopLevelItems(0, treeWidgetItems)
-
- def contextMenuEvent(self, pos):
- # 创建右键菜单
- context_menu = QMenu(self)
-
- # 添加删除选项
- delete_action = QAction("删除", self)
- delete_action.triggered.connect(self.delete_item)
- context_menu.addAction(delete_action)
-
- # 添加导出选项
- export_action = QAction("导出", self)
- export_action.triggered.connect(self.export_item)
- context_menu.addAction(export_action)
-
- context_menu.exec(widgets.qureyTreeWidget.mapToGlobal(pos))
-
- def delete_item(self):
- # 获取当前选中的项目
- selected_items = widgets.qureyTreeWidget.selectedItems()
- if not selected_items:
- QMessageBox.warning(self, '警告', '请先选择一个项目')
- return
-
- item = selected_items[0]
- data = item.data(0, Qt.UserRole + 1)
- if not data:
- self.warning = QMessageBox.warning(self, '警告', '所选项目没有关联的数据')
- return
-
- # 获取数据库路径和表名
- dbname = data['listData'][0]
- tablename = data['listData'][2]
- dbpath = os.path.join(os.path.abspath('../SQL'), f"{dbname}.db")
-
- # 确保 tablename 是 UTF-8 编码的字符串
- try:
- tablename_utf8 = tablename.encode('utf-8')
- except Exception as e:
- QMessageBox.critical(self, '错误', f'表名编码转换错误: {str(e)}')
- return
- # 获取父节点
- parent_item = item.parent()
- if not parent_item:
- QMessageBox.warning(self, '警告', '所选项目没有父节点')
- return
-
- parent_name = parent_item.text(0)
-
- # 确定要删除的表
- tables_to_delete = []
- if parent_name == '水准测段高差稳定计算':
- tables_to_delete = ['GC_Input_Param', 'GC_Input_Point', 'GC_Output_Point']
- elif parent_name == '控制网复测平面基准计算':
- tables_to_delete = ['GS_Input_Param', 'GS_Input_Point', 'GS_Result_Point', 'GS_Trans_Param',
- 'GS_Trans_Point']
- elif parent_name == '平面控制网稳定性计算':
- tables_to_delete = ['WD_Input_Param', 'WD_Input_Point', 'WD_Result_Param', 'WD_Result_Point']
- else:
- QMessageBox.warning(self, '警告', '未知的父节点')
- return
-
- # 确认删除操作
- reply = QMessageBox.question(self, '确认删除', f'确定要删除项目表 {tablename} 吗?',
- QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
- if reply == QMessageBox.No:
- return
-
- # 清空表
- try:
- conn = sqlite3.connect(dbpath)
- cursor = conn.cursor()
- for table in tables_to_delete:
- cursor.execute(f"DELETE FROM {table} WHERE TableName = ?", (tablename_utf8,))
- conn.commit()
- conn.close()
- QMessageBox.information(self, '成功', f'表 {tablename} 中的数据已从相关表中删除')
-
- # 刷新树状图
- self.refresh_tree()
- # 模拟点击 Enter 键 实现程序自动刷新的效果
- QTest.keyClick(widgets.qureyTreeWidget, Qt.Key_Return)
- except Exception as e:
- QMessageBox.critical(self, '错误', f'删除数据时出错: {str(e)}')
-
- def export_item(self):
- # 获取当前选中的项目
- selected_items = widgets.qureyTreeWidget.selectedItems()
- if not selected_items:
- QMessageBox.warning(self, '警告', '请先选择一个项目')
- return
-
- item = selected_items[0]
- data = item.data(0, Qt.UserRole + 1)
- if not data:
- QMessageBox.warning(self, '警告', '所选项目没有关联的数据')
- return
-
- # 获取数据库路径和表名
- dbname = data['listData'][0]
- tablename = data['listData'][2]
- tablename_utf8 = tablename.encode('utf-8')
- dbpath = os.path.join(os.path.abspath('../SQL'), f"{dbname}.db")
-
- # 获取父节点
- parent_item = item.parent()
- if not parent_item:
- QMessageBox.warning(self, '警告', '所选项目没有父节点')
- return
-
- parent_name = parent_item.text(0)
-
- # 根据父节点名称确定导出操作
- if parent_name == '水准测段高差稳定计算':
- GCExport.main_function(self, tablename_utf8, dbpath)
- elif parent_name == '控制网复测平面基准计算':
- GSExport.main_function(self, dbpath, tablename)
- elif parent_name == '平面控制网稳定性计算':
- WDExport.main_function(self, dbpath, tablename)
- else:
- QMessageBox.warning(self, '警告', '未知的父节点')
- return
-
- def refresh_tree(self):
- # 调用 MainWindow 的 refresh_tree 方法
- main_window = QApplication.instance().activeWindow()
- if isinstance(main_window, MainWindow):
- main_window.refresh_tree()
-
-
-
- # class DatabaseChangeHandler(FileSystemEventHandler):
- # def __init__(self, main_window):
- # self.main_window = main_window
- #
- # def on_modified(self, event):
- # # 忽略 .db-journal 文件的变化
- # if event.src_path.endswith('.db-journal'):
- # return
- # if event.src_path.endswith('.db'):
- # self.main_window.refresh_tree()
-
-
- class MainWindow(QMainWindow):
-
- def __init__(self):
- QMainWindow.__init__(self)
- self.file_path = None # 初始化时文件路径设置为None
- # super().__init__()
- # SET AS GLOBAL WIDGETS
- # ///////////////////////////////////////////////////////////////
- self.ui = Ui_MainWindow()
- self.ui.setupUi(self)
- # 连接信号与槽函数,实现点击操作
- self.ui.createFile.clicked.connect(self.on_create_file_clicked)
- self.ui.export_2.clicked.connect(self.on_export_2_clicked)
- # 初始化数据库监控
- # self.observer = Observer()
- # self.observer.schedule(DatabaseChangeHandler(self), path=os.path.abspath('../SQL'), recursive=False)
- # self.observer.start()
- # self.comboBox_2 = QComboBox(self)
- # ...此处为省略代码...
- global widgets
- widgets = self.ui
- widgets.search.clicked.connect(self.buttonClick)
- # 设置 datainfo 页面的焦点策略,使其能够捕获键盘事件
- widgets.datainfo.setFocusPolicy(Qt.StrongFocus)
- widgets.datainfo.keyPressEvent = self.datainfo_keyPressEvent
- # 是否使用系统自带标题栏 True是不使用,False使用
- # ///////////////////////////////////////////////////////////////
- Settings.ENABLE_CUSTOM_TITLE_BAR = True
-
- # APP名称
- # ///////////////////////////////////////////////////////////////
- title = "控制网复测平面基准归算程序"
- description = "控制网复测平面基准归算程序"
- # APPLY TEXTS
- self.setWindowTitle(title)
- widgets.titleRightInfo.setText(description)
-
- # TOGGLE MENU
- # ///////////////////////////////////////////////////////////////
- widgets.toggleButton.clicked.connect(lambda: UIFunctions.toggleMenu(self, True))
-
- # SET UI DEFINITIONS
- # ///////////////////////////////////////////////////////////////
- UIFunctions.uiDefinitions(self)
-
- # QTableWidget PARAMETERS
- # ///////////////////////////////////////////////////////////////
- # widgets.tableWidget.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
-
- # 点击事件
- # ///////////////////////////////////////////////////////////////
-
- # 左边菜单
- # 首页
- widgets.btn_home.clicked.connect(self.buttonClick)
- # 输入表格
- widgets.btn_widgets.clicked.connect(self.buttonClick)
- # 成果预览
- widgets.btn_new.clicked.connect(self.buttonClick)
- # 数据一览
- widgets.btn_data.clicked.connect(self.buttonClick)
- # 皮肤切换
- widgets.btn_message.clicked.connect(self.buttonClick)
- # 打开上传文件夹
- widgets.upload.clicked.connect(self.buttonClick)
- # 文件计算
- widgets.compute.clicked.connect(self.buttonClick)
- # 数据一览的搜索键
- widgets.search.clicked.connect(self.buttonClick)
-
- # 拓展左侧栏
- # def openCloseLeftBox():
- # UIFunctions.toggleLeftBox(self, True)
- # widgets.toggleLeftBox.clicked.connect(openCloseLeftBox)
- # widgets.extraCloseColumnBtn.clicked.connect(openCloseLeftBox)
-
- # EXTRA RIGHT BOX
- def openCloseRightBox():
- UIFunctions.toggleRightBox(self, True)
-
- widgets.settingsTopBtn.clicked.connect(openCloseRightBox)
-
- # 展示APP
- # ///////////////////////////////////////////////////////////////
- self.show()
-
- # 设置主题
- # ///////////////////////////////////////////////////////////////
- if getattr(sys, 'frozen', False):
- absPath = os.path.dirname(os.path.abspath(sys.executable))
- elif __file__:
- absPath = os.path.dirname(os.path.abspath(__file__))
- useCustomTheme = True
- self.useCustomTheme = useCustomTheme
- self.absPath = absPath
- themeFile = r"themes\py_dracula_light.qss"
-
- # 设置主题和HACKS
- if useCustomTheme:
- # LOAD AND APPLY STYLE
- UIFunctions.theme(self, themeFile, True)
-
- # SET HACKS
- AppFunctions.setThemeHack(self)
-
- # 设置主页和选择菜单
- # ///////////////////////////////////////////////////////////////
- widgets.stackedWidget.setCurrentWidget(widgets.home)
- widgets.btn_home.setStyleSheet(UIFunctions.selectMenu(widgets.btn_home.styleSheet()))
- # self.bind()
-
- # # 初始化树状数据库
- # self.refresh_tree()
-
- # tree_button = self.sql_init()
- # tree_button.itemClicked.connect(self.itembuttonClick)
- # tree_button.itemDoubleClicked.connect(self.itembuttonClick)
-
- # 单元格的右键
- def show_custom_context_menu(self, pos):
- # 创建一个右键菜单
- menu = QMenu(self.ui.resultTableView1)
- menu.setStyleSheet("QMenu { background-color: #FFFFFF; }")
- # 获取选中单元格的索引
- index = self.ui.resultTableView1.indexAt(pos)
- # # 添加菜单项和对应的操作
- # action_1 = QAction("操作1", self)
- # action_1.triggered.connect(lambda: self.do_something(index))
- # menu.addAction(action_1)
- # 添加菜单项和对应的操作
- action_1 = QAction("删除该行", self)
- action_1.triggered.connect(self.seleceModel_itemclicked)
- menu.addAction(action_1)
- action_2 = QAction("编辑单元格", self)
- action_2.triggered.connect(self.seleceModel_itemclicked)
- menu.addAction(action_2)
- action_3 = QAction("添加数据", self)
- action_3.triggered.connect(self.seleceModel_itemclicked)
- menu.addAction(action_3)
- menu.exec(self.ui.resultTableView1.mapToGlobal(pos))
-
- # def closeEvent(self, event):
- # # 停止监控
- # self.observer.stop()
- # self.observer.join()
- # event.accept()
-
- # 绑定组件
- def bind(self):
- # 计算
- widgets.compute.clicked.connect(self.buttonClick)
-
- # 删除tableview
- def delete_table_view(table_view):
- table_view.setParent(None)
- table_view.deleteLater()
-
- # ///////////////////////////////////////////////////////////////
- def buttonClick(self):
- # GET BUTTON CLICKED
- btn = self.sender()
- btnName = btn.objectName()
-
- # 首页
- if btnName == "btn_home":
- widgets.stackedWidget.setCurrentWidget(widgets.home)
- UIFunctions.resetStyle(self, btnName)
- btn.setStyleSheet(UIFunctions.selectMenu(btn.styleSheet()))
-
- # 输入表格
- if btnName == "btn_widgets":
- widgets.stackedWidget.setCurrentWidget(widgets.widgets)
- UIFunctions.resetStyle(self, btnName)
- btn.setStyleSheet(UIFunctions.selectMenu(btn.styleSheet()))
-
- # 成果预览
- if btnName == "btn_new":
- widgets.stackedWidget.setCurrentWidget(widgets.new_page) # SET PAGE
- UIFunctions.resetStyle(self, btnName) # RESET ANOTHERS BUTTONS SELECTED
- btn.setStyleSheet(UIFunctions.selectMenu(btn.styleSheet())) # SELECT MENU
-
- # 数据一览
- if btnName == "btn_data":
- # 初始化树状数据库
- self.refresh_tree()
- widgets.stackedWidget.setCurrentWidget(widgets.datainfo) # SET PAGE
- UIFunctions.resetStyle(self, btnName) # RESET ANOTHERS BUTTONS SELECTED
- btn.setStyleSheet(UIFunctions.selectMenu(btn.styleSheet())) # SELECT MENU
-
- # 皮肤切换
- if btnName == "btn_message":
- if self.useCustomTheme:
- themeFile = os.path.abspath(os.path.join(self.absPath, "themes/py_dracula_dark.qss"))
- UIFunctions.theme(self, themeFile, True)
- # SET HACKS
- AppFunctions.setThemeHack(self)
- self.useCustomTheme = False
- else:
- themeFile = os.path.abspath(os.path.join(self.absPath, "themes/py_dracula_light.qss"))
- UIFunctions.theme(self, themeFile, True)
- # SET HACKS
- AppFunctions.setThemeHack(self)
- self.useCustomTheme = True
- # 文件上传
- if btnName == "upload":
- # 使用 QFileDialog 获取文件路径
- file_path, _ = QFileDialog.getOpenFileName(
- self,
- "选择文件",
- "",
- "表格文件 (*.xls *.xlsx)"
- # 水准后期添加支持.xls文件
- )
- if file_path:
- # 处理选中的文件
- self.file_path = file_path # 将获取的路径保存到类的属性中
- UIFunctions.execute_script_based_on_selection(self, file_path)
-
- # 文件计算
- if btnName == "compute":
- if self.file_path: # 确保有文件路径后再进行处理
- # 计算与展示的业务代码
- UIFunctions.compute_show_process_excel_file(self, self.file_path)
- # 1秒后自动跳转
- QTimer.singleShot(1000, lambda: self.simulateButtonClick("btn_new"))
- else:
- QMessageBox.warning(self, '警告', '请先选择项目并上传文件')
-
- # 树状查询
- if btnName == "search":
- self.searchClick()
-
- # 输出点击回馈
- print(f'Button "{btnName}" pressed!')
-
- # 辅助函数,点击计算后自动跳转页面
- def simulateButtonClick(self, btnName):
- # 根据按钮名称找到对应的按钮
- btn = self.findChild(QObject, btnName)
- if btn:
- # 触发按钮点击事件
- btn.click()
-
- # 新增槽函数来调用 create_database_and_tables
- def on_create_file_clicked(self):
- Back.Program_Run.database_operations.create_database_and_tables(self, self.ui)
-
- # 定义导出数据库的槽函数
- def on_export_2_clicked(self):
- if self.file_path:
- UIFunctions.export_database_to_excel(self, self.file_path)
- else:
- QMessageBox.warning(self, '警告', '请先选择项目并上传文件')
-
- # RESIZE EVENTS
- # ///////////////////////////////////////////////////////////////
- def resizeEvent(self, event):
- # Update Size Grips
- UIFunctions.resize_grips(self)
-
- # 鼠标点击事件
- # ///////////////////////////////////////////////////////////////
- def mousePressEvent(self, event):
- # SET DRAG POS WINDOW
- # self.dragPos = event.globalPos()
- self.dragPos = event.globalPosition().toPoint() # 设置鼠标拖动位置
-
- # 输出鼠标事件
- if event.buttons() == Qt.LeftButton:
- print('Mouse click: LEFT CLICK')
- if event.buttons() == Qt.RightButton:
- print('Mouse click: RIGHT CLICK')
-
- # 设一个全局变量,存数据库中所有的包含内容(数据库-三种方法-表)
- dblist = []
-
- # 初始化数据一览(数据库全展示)
- def sql_init(self):
- # 清空 dblist 以确保每次初始化时都是空的
- self.dblist = []
- # 初始化全部数据库
- # inpath = r'D:\4work_now\20240819GS\20241211\SQL'
- inpath = os.path.abspath('../SQL')
- # 读取所有的数据库名
- sqlitem = []
- id = 1
- for filename in os.listdir(inpath):
- # 数据库
- dbname = filename.split('.', -1)[0]
- dbpath = os.path.join(inpath, filename)
- sqlitem.append(TreeWidgetItem(id, 0, dbname, icon=QIcon(
- os.path.abspath(os.path.join(self.absPath, "images/icons/cil-clone.png")))))
- pid = id
- id = id + 1
- # 三种方法
- sqlitem.append(TreeWidgetItem(id, pid, '水准测段高差稳定计算', icon=QIcon(
- os.path.join(self.absPath, "images/icons/cil-description.png"))))
- gcid = id
- id = id + 1
- sqlitem.append(TreeWidgetItem(id, pid, '控制网复测平面基准计算', icon=QIcon(
- os.path.join(self.absPath, "images/icons/cil-description.png"))))
- gsid = id
- id = id + 1
- sqlitem.append(TreeWidgetItem(id, pid, '平面控制网稳定性计算', icon=QIcon(
- os.path.join(self.absPath, "images/icons/cil-description.png"))))
- wdid = id
- id = id + 1
- # 读取所有的表名(三种方式往下)
- db1 = sqlite3.connect(dbpath)
- # 获取游标
- cursor1 = db1.cursor()
- sqlstr1 = 'SELECT TableName FROM GC_Input_Param;'
- cursor1.execute(sqlstr1)
- result1 = cursor1.fetchall()
- for re1 in result1:
- str1 = re1[0].decode('utf-8')
- list1 = []
- list1.append(dbname)
- list1.append('水准测段高差稳定计算')
- list1.append(str1)
- self.dblist.append(list1)
- sqlitem.append(TreeWidgetItem(id, gcid, str1, icon=QIcon(
- os.path.join(self.absPath, "images/icons/cil-file.png")), extend={'listData': list1}))
- id = id + 1
- sqlstr2 = 'SELECT TableName FROM GS_Input_Param;'
- cursor1.execute(sqlstr2)
- result2 = cursor1.fetchall()
- for re2 in result2:
- str2 = re2[0].decode('utf-8')
- list2 = []
- list2.append(dbname)
- list2.append('控制网复测平面基准计算')
- list2.append(str2)
- self.dblist.append(list2)
- sqlitem.append(TreeWidgetItem(id, gsid, str2,
- icon=QIcon(os.path.join(self.absPath, "images/icons/cil-file.png")),
- extend={'listData': list2}))
- id = id + 1
- sqlstr3 = 'SELECT TableName FROM WD_Input_Param;'
- cursor1.execute(sqlstr3)
- result3 = cursor1.fetchall()
- for re3 in result3:
- str3 = re3[0].decode('utf-8')
- list3 = []
- list3.append(dbname)
- list3.append('平面控制网稳定性计算')
- list3.append(str3)
- self.dblist.append(list3)
- sqlitem.append(TreeWidgetItem(id, wdid, str3,
- icon=QIcon(os.path.join(self.absPath, "images/icons/cil-file.png")),
- extend={'listData': list3}))
- id = id + 1
- button = ElTree(ElTreeData(sqlitem))
- return button
-
- # 刷新树状图
- def refresh_tree(self):
- # 清空当前的树状图
- widgets.allTreeWidget.clear()
- # 重新初始化树状图
- tree_button = self.sql_init()
- tree_button.itemClicked.connect(self.itembuttonClick)
- tree_button.itemDoubleClicked.connect(self.itembuttonClick)
-
- # 关键词查询
- def searchClick(self):
- # GET BUTTON CLICKED
- btn = self.sender()
- btnName = btn.objectName()
- # 获取文本
- text1 = self.ui.lineEdit_2.text()
- # 符合的list
- fhlist = []
- # 查询(待优化)
- for list1 in self.dblist:
- for li in list1:
- if text1 in li:
- fhlist.append(list1)
- break
- # 更新item值
- sqlitem = []
- # 前两层是否一致
- str1 = ''
- str2 = ''
- id = 1
- pid = 0
- fid = 0
- zdy = []
- for list2 in fhlist:
- dbname = list2[0]
- if dbname != str1:
- str1 = dbname
- pid = id
- str2 = ''
- sqlitem.append(TreeWidgetItem(id, 0, dbname, icon=QIcon(
- os.path.join(self.absPath, "images/icons/cil-clone.png"))))
- zdy1 = []
- zdy1.append(id)
- zdy1.append(0)
- zdy1.append(dbname)
- zdy.append(zdy1)
- id = id + 1
- mename = list2[1]
- if mename != str2:
- str2 = mename
- fid = id
- sqlitem.append(TreeWidgetItem(id, pid, mename, icon=QIcon(
- os.path.join(self.absPath, "images/icons/cil-description.png"))))
- zdy1 = []
- zdy1.append(id)
- zdy1.append(pid)
- zdy1.append(mename)
- zdy.append(zdy1)
- id = id + 1
- sqlitem.append(TreeWidgetItem(id, fid, list2[2], icon=QIcon(
- os.path.join(self.absPath, "images/icons/cil-file.png")), extend={'listData': list2}))
- zdy1 = []
- zdy1.append(id)
- zdy1.append(fid)
- zdy1.append(list2[2])
- zdy.append(zdy1)
- id = id + 1
- search_button = ElTree1(ElTreeData(sqlitem))
- search_button.itemClicked.connect(self.itembuttonClick1)
- search_button.itemDoubleClicked.connect(self.itembuttonClick1)
- # 隐藏默认label
- self.ui.defaultLabel.setVisible(False)
-
- # 全树的item展示
- def itembuttonClick(self):
- # 判定是否获取的是根节点
- pd = 1
- select_item = self.ui.allTreeWidget.currentItem()
- # 获取点击的item的text和它对应的上两个节点
- str1 = select_item.text(0)
- current_text = '' # 初始化 current_text
- str3 = '' # 初始化 str3
- try:
- pa_item = select_item.parent()
- current_text = pa_item.text(0)
- z_item = pa_item.parent()
- str3 = z_item.text(0)
- except:
- pd = -1
- if current_text == '':
- pd = -1
- if str3 == '':
- pd = -1
- if pd == -1:
- pass
- else:
- # 数据库目录
- inpath = os.path.abspath('../SQL')
- file_path = inpath + '/' + str3 + '.db'
- # 数据库路径,哪种方法,表名
- self.selectModel = UIFunctions.search_data_to_show(self, file_path, current_text, str1)
- # self.ui.resultTableView1.doubleClicked.connect(self.seleceModel_itemclicked)
-
- # 设置右键菜单策略为CustomContextMenu
- self.ui.resultTableView1.setContextMenuPolicy(Qt.CustomContextMenu)
-
- # 关联自定义的右键菜单方法到customContextMenuRequested信号
- self.ui.resultTableView1.customContextMenuRequested.connect(self.show_custom_context_menu)
-
- # 右键对应行可删除对应行(只是视图上)
- def seleceModel_itemclicked(self):
- curIndex = self.selectModel.currentIndex()
- self.ui.resultTableView1.model().removeRow(curIndex.row())
- kk = 1
-
- # 搜索的item展示
- def itembuttonClick1(self):
- # 判定是否获取的是根节点
- pd = 1
- select_item = self.ui.qureyTreeWidget.currentItem()
- # 获取点击的item的text和它对应的上两个节点
- str1 = select_item.text(0)
- current_text = '' # 初始化 current_text
- str3 = '' # 初始化 str3
- try:
- pa_item = select_item.parent()
- current_text = pa_item.text(0)
- z_item = pa_item.parent()
- str3 = z_item.text(0)
- except:
- pd = -1
- if current_text == '':
- pd = -1
- if str3 == '':
- pd = -1
- if pd == -1:
- pass
- else:
- # 数据库目录
- inpath = os.path.abspath('../SQL')
- file_path = inpath + '/' + str3 + '.db'
- # 数据库路径,哪种方法,表名
- UIFunctions.search_data_to_show(self, file_path, current_text, str1)
- # self.ui.resultTableView1.doubleClicked.connect(self.seleceModel_itemclicked)
-
- # 设置右键菜单策略为CustomContextMenu
- self.ui.resultTableView1.setContextMenuPolicy(Qt.CustomContextMenu)
-
- # 关联自定义的右键菜单方法到customContextMenuRequested信号
- self.ui.resultTableView1.customContextMenuRequested.connect(self.show_custom_context_menu)
-
- # 键盘回车事件,目前用于搜索按钮
- def datainfo_keyPressEvent(self, event):
- if event.key() == Qt.Key_Return or event.key() == Qt.Key_Enter:
- # 检查 lineEdit_2 中是否有内容
- if widgets.lineEdit_2.text():
- # 模拟 search 按钮点击事件
- self.ui.search.click()
- else:
- # 调用默认的 keyPressEvent 处理其他按键事件
- super(widgets.datainfo.__class__, widgets.datainfo).keyPressEvent(event)
-
-
- if __name__ == "__main__":
- app = QApplication(sys.argv)
- app.setWindowIcon(QIcon("icon.ico"))
- window = MainWindow()
- # window.resize(1440, 960) # 高宽
- sys.exit(app.exec())
|