Exemple #1
0
class WidgetDemo(QWidget):
    def __init__(self, model, rows, columns):
        super(WidgetDemo, self).__init__()
        self.init_rows = rows
        self.init_columns = columns
        self.model = model
        self.initUI(model)

    def initUI(self, model):
        self.resize(800, 800)
        self.res_pos = []
        self.focus_pos = None
        self.var_list = None
        self.signal = MySignal()
        #菜单栏
        self.menu = QMenuBar()
        self.file = self.menu.addMenu('文件')
        self.edit = self.menu.addMenu('编辑')
        self.view = self.menu.addMenu('视图')
        self.help = self.menu.addMenu('帮助')
        #各菜单下的子菜单

        #文件菜单下的子菜单
        # self.new = self.file.addAction('新建')
        self.open = self.file.addAction('打开')
        self.save = self.file.addAction('保存')
        # self.save_as = self.file.addAction('另存为')

        #编辑菜单下的子菜单
        self.cut = self.edit.addAction('剪切')
        self.copy = self.edit.addAction('复制')
        self.paste = self.edit.addAction('粘贴')
        self.delete = self.edit.addAction('删除')
        self.find = self.edit.addAction('查找')
        self.replace = self.edit.addAction('替换')

        # 快捷键
        self.open.setShortcut('Ctrl+O')
        self.save.setShortcut('Ctrl+S')
        # self.new.setShortcut('Ctrl+N')
        self.find.setShortcut('Ctrl+F')

        #视图菜单下的子菜单
        self.tool_view = QAction('工具栏', checkable=True)
        self.tool_view.setChecked(True)
        self.view.addAction(self.tool_view)

        self.statu_view = QAction('状态栏', checkable=True)
        self.statu_view.setChecked(True)
        self.view.addAction(self.statu_view)

        #帮助菜单下的子菜单
        self.about = self.help.addAction('关于')

        #工具栏
        self.tool_bar = QToolBar()
        # self.tool_bar.addAction(self.new)
        self.tool_bar.addAction(self.open)
        self.tool_bar.addAction(self.save)
        self.tool_bar.addAction(self.cut)
        self.tool_bar.addAction(self.copy)
        self.tool_bar.addAction(self.paste)
        self.tool_bar.addAction(self.find)
        # self.setting = QAction('变量设置')
        # self.setting.setEnabled(False)
        # self.tool_bar.addAction(self.setting)
        # self.tool_bar.addAction(self.replace)

        # #tool文本显示在下方
        # self.tool_bar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)

        #findWidge
        self.find_widget = FindWidget()
        self.find_widget.hide()

        #表格
        self.table_view = QTableView()
        self.table_view.setModel(self.model)

        #状态栏
        self.status_bar = QStatusBar()
        self.status_bar.showMessage('状态栏')

        # 右键菜单栏
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.context_menu = QMenu()
        self.addRow_action = self.context_menu.addAction('增加一行')
        self.addRow_action.triggered.connect(self.addRow)
        self.delRow_action = self.context_menu.addAction('删除一行')
        self.delRow_action.triggered.connect(
            lambda: self.model.removeRow(self.table_view.currentIndex().row()))
        self.addColumn_action = self.context_menu.addAction('增加一列')
        self.addColumn_action.triggered.connect(self.addColumn)
        self.delColumn_action = self.context_menu.addAction('删除一列')
        self.delColumn_action.triggered.connect(
            lambda: self.model.removeColumn(self.table_view.currentIndex().
                                            column()))
        self.customContextMenuRequested.connect(self.rightMenuShow)

        #创建布局
        layout = QVBoxLayout()
        layout.addWidget(self.menu)
        layout.addWidget(self.tool_bar)
        layout.addWidget(self.find_widget)
        layout.addWidget(self.table_view)
        layout.addWidget(self.status_bar)
        self.setLayout(layout)

        #关联信号
        self.open.triggered.connect(self.triggeredOpen)
        self.save.triggered.connect(self.triggeredSave)
        self.tool_view.triggered.connect(self.triggeredView)
        self.statu_view.triggered.connect(self.triggeredView)
        # self.new.triggered.connect(self.triggeredNew)
        self.find.triggered.connect(self.triggeredFind)
        self.find_widget.search.triggered.connect(self.dataLocation)
        self.find_widget.down_aciton.triggered.connect(self.downAcitonLocation)
        self.find_widget.up_aciton.triggered.connect(self.upAcitonLocation)
        self.find_widget.close_aciton.triggered.connect(self.triggeredHideFind)
        self.find_widget.repalce_button.clicked.connect(self.onClickReplace)
        self.find_widget.repalceAll_button.clicked.connect(
            self.onClickReplaceAll)
        # self.setting.triggered.connect(self.triggeredSetting)

        #美化
        icon = QIcon()
        icon.addPixmap(QPixmap('./image/打开.png'), QIcon.Normal, QIcon.Off)
        self.open.setIcon(icon)
        icon.addPixmap(QPixmap('./image/保存.png'), QIcon.Normal, QIcon.Off)
        self.save.setIcon(icon)
        # icon.addPixmap(QPixmap('./image/新建.png'), QIcon.Normal, QIcon.Off)
        # self.new.setIcon(icon)
        icon.addPixmap(QPixmap('./image/剪切.png'), QIcon.Normal, QIcon.Off)
        self.cut.setIcon(icon)
        icon.addPixmap(QPixmap('./image/复制.png'), QIcon.Normal, QIcon.Off)
        self.copy.setIcon(icon)
        icon.addPixmap(QPixmap('./image/粘贴.png'), QIcon.Normal, QIcon.Off)
        self.paste.setIcon(icon)
        icon.addPixmap(QPixmap('./image/查找1.png'), QIcon.Normal, QIcon.Off)
        self.find.setIcon(icon)
        # icon.addPixmap(QPixmap('./image/设置.png'), QIcon.Normal, QIcon.Off)
        # self.setting.setIcon(icon)
        # icon.addPixmap(QPixmap('./image/替换.png'), QIcon.Normal, QIcon.Off)
        # self.replace.setIcon(icon)

    def showProgress(self, msg):
        self.status_bar.showMessage(msg)

    def loadData(self, model):
        print('load...')
        self.model = model
        self.table_view.setModel(self.model)
        qApp.processEvents()

    def triggeredOpen(self):
        self.status_bar.showMessage('打开文件', 5000)
        self.dialog = QFileDialog()
        self.dialog.setFileMode(QFileDialog.AnyFile)
        dir = r'D:/Learn-python-notes/projects/demo/Work/TCM_DSAS/data'
        self.dialog.setDirectory(dir)
        self.dialog.setFilter(QDir.Files)
        if self.dialog.exec_():
            try:
                file_name = self.dialog.selectedFiles()[0]
                #这里线程实例化一定要实例化成员变量,否则线程容易销毁
                self.thread = ReaderExcelThread(file_name)
                self.thread.standarModel_signal.connect(self.loadData)
                self.thread.progressRate_signal.connect(self.showProgress)
                self.thread.finished_signal.connect(self.thread.quit)
                self.thread.start()
                # self.setting.setEnabled(True)
            except Exception as e:
                print(e)
                pass

    def triggeredSave(self):
        self.status_bar.showMessage('保存文件', 5000)
        file_path, _ = QFileDialog.getSaveFileName(
            self, '保存文件', './data',
            'ALL Files(*);;xlsx(*.xlsx);;xls(*.xls);;csv(*.csv)')
        if file_path == '':
            return
        # 文件中写入数据
        try:
            self.write_thread = WriteExcelThread(file_path, self.model)
            self.write_thread.start_signal.connect(self.showProgress)
            self.write_thread.end_signal.connect(self.write_thread.quit)
            self.write_thread.start()
            self.status_bar.showMessage('保存完毕!')
        except Exception as e:
            print(e)

    #状态栏与工具栏的显示和隐藏
    def triggeredView(self, state):
        sender = self.sender().text()
        if sender == '工具栏':
            if state:
                self.tool_bar.show()
            else:
                self.tool_bar.hide()
        else:
            if state:
                self.status_bar.show()
            else:
                self.status_bar.hide()

    # def triggeredNew(self):
    #     print('New')
    #     pass

    def triggeredFind(self):
        self.find_widget.show()

    #重载信号,实现ESC隐藏查找窗口
    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self.find_widget.hide()

    #聚焦到某个cell
    def positionFocus(self, x, y):
        self.table_view.verticalScrollBar().setSliderPosition(x)
        self.table_view.horizontalScrollBar().setSliderPosition(y)
        self.table_view.openPersistentEditor(self.model.index(x, y))
        self.table_view.setFocus()

    #得到所以匹配项的位置
    def dataLocation(self):
        self.changeCellColor()
        text = self.find_widget.line_edit1.text()
        self.res_pos = []
        flag = 0
        rows = self.model.rowCount()
        columns = self.model.columnCount()
        try:
            for row in range(rows):
                for column in range(columns):
                    if text == self.model.index(row, column).data():
                        self.res_pos.append((row, column))
                        item = self.model.item(row, column)
                        item.setBackground(QColor(255, 255, 0))
                        item.setForeground(QColor(255, 0, 0))
                        #转到到第一个匹配值的位置,并处于可编辑状态
                        if not flag:
                            flag = 1
                            self.positionFocus(row, column)
                            self.focus_pos = 0
        except Exception as e:
            print(e)

    #向下跳转
    def downAcitonLocation(self):
        cnt = len(self.res_pos)
        if cnt == 0 or self.focus_pos == cnt - 1:
            return
        try:
            self.table_view.closePersistentEditor(
                self.model.index(self.res_pos[self.focus_pos][0],
                                 self.res_pos[self.focus_pos][1]))
            x, y = self.res_pos[self.focus_pos + 1]
            self.positionFocus(x, y)
            self.focus_pos += 1
        except Exception as e:
            print(e)

    # 向上跳转
    def upAcitonLocation(self):
        cnt = len(self.res_pos)
        if cnt == 0 or self.focus_pos == 0:
            return
        try:
            self.table_view.closePersistentEditor(
                self.model.index(self.res_pos[self.focus_pos][0],
                                 self.res_pos[self.focus_pos][1]))
            x, y = self.res_pos[self.focus_pos - 1]
            self.positionFocus(x, y)
            self.focus_pos -= 1
        except Exception as e:
            print(e)

    def triggeredHideFind(self):
        self.changeCellColor()
        self.find_widget.hide()

    def changeCellColor(self):
        if self.res_pos is not None and len(self.res_pos):
            self.table_view.closePersistentEditor(
                self.model.index(self.res_pos[self.focus_pos][0],
                                 self.res_pos[self.focus_pos][1]))
            for item in self.res_pos:
                x, y = item
                item = self.model.item(x, y)
                item.setBackground(QColor(255, 255, 255))
                item.setForeground(QColor(0, 0, 0))

    def onClickReplace(self):
        cnt = len(self.res_pos)
        text = self.find_widget.line_edit2.text()
        if self.res_pos is None or cnt == 0:
            return
        try:
            x, y = self.res_pos[self.focus_pos]
            self.model.setItem(x, y, QStandardItem(text))
        except Exception as e:
            print(e)

    def onClickReplaceAll(self):
        cnt = len(self.res_pos)
        if self.res_pos is None or cnt == 0:
            return
        try:
            text = self.find_widget.line_edit2.text()
            for x, y in self.res_pos:
                self.model.setItem(x, y, QStandardItem(text))
        except Exception as e:
            print(e)

    # #设置变量
    # def triggeredSetting(self):
    #     self.getVar_thread = GetVarThread(self.model)
    #     self.getVar_thread.send_signal.connect(self.initVarList)
    #     self.getVar_thread.end_signal.connect(self.getVar_thread.quit)
    #     self.getVar_thread.start()
    #
    #
    #
    # def initVarList(self,var_list):
    #     dialog = VariableSettingWindow.VariableSettingWindowDemo(var_list)
    #     dialog.signal.sender.connect(self.getVarList)
    #     dialog.show()
    #
    # def getVarList(self,lst):
    #     self.var_list = lst
    # print(lst)

    def addRow(self):
        # 当前行的下方添加一行
        try:
            self.model.insertRows(self.table_view.currentIndex().row() + 1, 1)
        except Exception as e:
            print(e)

    def addColumn(self):
        self.model.insertColumns(self.table_view.currentIndex().column() + 1,
                                 1)

    def rightMenuShow(self):
        try:
            #菜单显示的位置
            self.context_menu.popup(QCursor.pos())
            self.context_menu.show()
        except Exception as e:
            print(e)
Exemple #2
0
class WidgetDemo(QWidget):
    def __init__(self,mode):
        super(WidgetDemo,self).__init__()
        self.mode = mode
        self.initUI(mode)

    def initUI(self,mode):
        self.resize(800,800)
        #这里初始化,便于直接输入数据
        self.data = [['']*100 for i in range(15000)]
        self.res_pos = []
        self.focus_pos = None
        self.var_list = None
        #菜单栏
        self.menu = QMenuBar()
        self.file = self.menu.addMenu('文件')
        self.edit = self.menu.addMenu('编辑')
        self.view = self.menu.addMenu('视图')
        self.help = self.menu.addMenu('帮助')
        #各菜单下的子菜单

        #文件菜单下的子菜单
        self.new = self.file.addAction('新建')
        self.open = self.file.addAction('打开')
        self.save = self.file.addAction('保存')
        # self.save_as = self.file.addAction('另存为')


        #编辑菜单下的子菜单
        self.cut = self.edit.addAction('剪切')
        self.copy = self.edit.addAction('复制')
        self.paste = self.edit.addAction('粘贴')
        self.delete = self.edit.addAction('删除')
        self.find = self.edit.addAction('查找')
        self.replace = self.edit.addAction('替换')

        # 快捷键
        self.open.setShortcut('Ctrl+O')
        self.save.setShortcut('Ctrl+S')
        self.new.setShortcut('Ctrl+N')
        self.find.setShortcut('Ctrl+F')

        #视图菜单下的子菜单
        self.tool_view = QAction('工具栏',checkable=True)
        self.tool_view.setChecked(True)
        self.view.addAction(self.tool_view)

        self.statu_view = QAction('状态栏',checkable=True)
        self.statu_view.setChecked(True)
        self.view.addAction(self.statu_view)


        #帮助菜单下的子菜单
        self.about = self.help.addAction('关于')

        #工具栏
        self.tool_bar = QToolBar()
        self.tool_bar.addAction(self.new)
        self.tool_bar.addAction(self.open)
        self.tool_bar.addAction(self.save)
        self.tool_bar.addAction(self.cut)
        self.tool_bar.addAction(self.copy)
        self.tool_bar.addAction(self.paste)
        self.tool_bar.addAction(self.find)
        self.setting = QAction('变量设置')
        self.setting.setEnabled(False)
        self.tool_bar.addAction(self.setting)
        # self.tool_bar.addAction(self.replace)

        # #tool文本显示在下方
        # self.tool_bar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)

        #findWidge
        self.find_widget = FindWidget()
        self.find_widget.hide()

        #表格
        self.table_view = QTableView()
        self.table_view.setModel(self.mode)

        #状态栏
        self.status_bar = QStatusBar()
        self.status_bar.showMessage('这是一个状态栏')


        #创建布局
        layout = QVBoxLayout()
        layout.addWidget(self.menu)
        layout.addWidget(self.tool_bar)
        layout.addWidget(self.find_widget)
        layout.addWidget(self.table_view)
        layout.addWidget(self.status_bar)
        self.setLayout(layout)

        #关联信号
        self.open.triggered.connect(self.triggeredOpen)
        self.save.triggered.connect(self.triggeredSave)
        self.mode.itemChanged.connect(self.dealItemChanged)
        self.tool_view.triggered.connect(self.triggeredView)
        self.statu_view.triggered.connect(self.triggeredView)
        self.new.triggered.connect(self.triggeredNew)
        self.find.triggered.connect(self.triggeredFind)
        self.find_widget.search.triggered.connect(self.dataLocation)
        self.find_widget.down.triggered.connect(self.downLocation)
        self.find_widget.up.triggered.connect(self.upLocation)
        self.find_widget.close.triggered.connect(self.triggeredHideFind)
        self.find_widget.repalce_button.clicked.connect(self.onClickReplace)
        self.find_widget.repalceAll_button.clicked.connect(self.onClickReplaceAll)
        self.setting.triggered.connect(self.triggeredSetting)


        #美化
        icon = QIcon()
        icon.addPixmap(QPixmap('../image/打开.png'), QIcon.Normal, QIcon.Off)
        self.open.setIcon(icon)
        icon.addPixmap(QPixmap('../image/保存.png'), QIcon.Normal, QIcon.Off)
        self.save.setIcon(icon)
        icon.addPixmap(QPixmap('../image/新建.png'), QIcon.Normal, QIcon.Off)
        self.new.setIcon(icon)
        icon.addPixmap(QPixmap('../image/剪切.png'), QIcon.Normal, QIcon.Off)
        self.cut.setIcon(icon)
        icon.addPixmap(QPixmap('../image/复制.png'), QIcon.Normal, QIcon.Off)
        self.copy.setIcon(icon)
        icon.addPixmap(QPixmap('../image/粘贴.png'), QIcon.Normal, QIcon.Off)
        self.paste.setIcon(icon)
        icon.addPixmap(QPixmap('../image/查找1.png'), QIcon.Normal, QIcon.Off)
        self.find.setIcon(icon)
        icon.addPixmap(QPixmap('../image/设置.png'), QIcon.Normal, QIcon.Off)
        self.setting.setIcon(icon)
        # icon.addPixmap(QPixmap('../image/替换.png'), QIcon.Normal, QIcon.Off)
        # self.replace.setIcon(icon)



    def triggeredOpen(self):
        self.status_bar.showMessage('打开文件',5000)
        self.dialog = QFileDialog()
        self.dialog.setFileMode(QFileDialog.AnyFile)
        dir = r'../data'
        self.dialog.setDirectory(dir)
        self.dialog.setFilter(QDir.Files)
        if self.dialog.exec_():
            try:
                start = time.time()
                file_name = self.dialog.selectedFiles()[0]
                #这里读取数据返回列表便于表格中数据的更新
                data_list = read_xlsx(file_name)
                self.data = data_list
                self.mode = QStandardItemModel()
                for rows in data_list:
                    row = [QStandardItem(str(cell)) for cell in rows]
                    self.mode.appendRow(row)
                self.mode.itemChanged.connect(self.dealItemChanged)
                self.table_view.setModel(self.mode)
                # self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
                self.table_view.resizeColumnsToContents()
                self.table_view.resizeRowsToContents()
                end = time.time()
                self.status_bar.showMessage('数据加载完毕,耗时{}秒'.format(end-start))
                self.setting.setEnabled(True)
            except Exception as e:
                print(e)
                pass

    def triggeredSave(self):
        self.status_bar.showMessage('保存文件', 5000)
        file_path, _ = QFileDialog.getSaveFileName(self, '保存文件', '../data',
                                                           'ALL Files(*);;xlsx(*.xlsx);;xls(*.xls);;csv(*.csv)')
        if file_path == '':
            return
        # 文件中写入数据
        try:
            wb = workbook.Workbook()
            wb.encoding = 'utf-8'
            wa = wb.active
            for item in self.data:
                # 过滤无效数据
                try:
                    if ''.join(item) == '':
                        continue
                except:
                    pass
                wa.append(item)
            wb.save(file_path)
            self.status_bar.showMessage('保存完毕!')
        except Exception as e:
            print(e)


    #数据变化信号处理
    def dealItemChanged(self,item):
        try:
            row,column = item.row(),item.column()
            self.data[row][column] = item.text()
        except Exception as e:
            print(e)
            pass

    #状态栏与工具栏的显示和隐藏
    def triggeredView(self,state):
        sender = self.sender().text()
        if sender == '工具栏':
            if state:
                self.tool_bar.show()
            else:
                self.tool_bar.hide()
        else:
            if state:
                self.status_bar.show()
            else:
                self.status_bar.hide()

    def triggeredNew(self):
        print('New')
        pass

    def triggeredFind(self):
        self.find_widget.show()

    #重载信号,实现ESC隐藏查找窗口
    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self.find_widget.hide()

    #聚焦到某个cell
    def positionFocus(self,x,y):
        self.table_view.verticalScrollBar().setSliderPosition(x)
        self.table_view.horizontalScrollBar().setSliderPosition(y)
        self.table_view.openPersistentEditor(self.mode.index(x, y))
        self.table_view.setFocus()

    #得到所以匹配项的位置
    def dataLocation(self):
        text = self.find_widget.line_edit1.text()
        self.res_pos = []
        flag = 0
        for i,row in enumerate(self.data):
            try:
                if ''.join(row) == '':
                    continue
            except:
                pass
            for j,cell in enumerate(row):
                if text == str(cell):
                    # print(i,j)
                    self.res_pos.append((i,j))
                    item = self.mode.item(i,j)
                    item.setBackground(QColor(255, 255, 0))
                    item.setForeground(QColor(255, 0, 0))
                    #转到到第一个匹配值的位置,并处于可编辑状态
                    if not flag:
                        flag = 1
                        self.positionFocus(i,j)
                        self.focus_pos = 0

    #向下跳转
    def downLocation(self):
        cnt = len(self.res_pos)
        if cnt == 0 or self.focus_pos == cnt-1:
            return
        try:
            self.table_view.closePersistentEditor(
                self.mode.index(self.res_pos[self.focus_pos][0],self.res_pos[self.focus_pos][1]))
            x, y = self.res_pos[self.focus_pos + 1]
            self.positionFocus(x,y)
            self.focus_pos += 1
        except Exception as e:
            print(e)

    # 向上跳转
    def upLocation(self):
        cnt = len(self.res_pos)
        if cnt == 0 or self.focus_pos == 0:
            return
        try:
            self.table_view.closePersistentEditor(
                self.mode.index(self.res_pos[self.focus_pos][0], self.res_pos[self.focus_pos][1]))
            x, y = self.res_pos[self.focus_pos - 1]
            self.positionFocus(x, y)
            self.focus_pos -= 1
        except Exception as e:
            print(e)


    def triggeredHideFind(self):
        if self.res_pos is not None and len(self.res_pos):
            self.table_view.closePersistentEditor(
                self.mode.index(self.res_pos[self.focus_pos][0], self.res_pos[self.focus_pos][1]))
            for item in self.res_pos:
                x,y = item
                item = self.mode.item(x,y)
                item.setBackground(QColor(255, 255, 255))
                item.setForeground(QColor(0, 0, 0))
        self.find_widget.hide()


    #不清楚如何修改cell值,替换功能暂时无法上线
    def onClickReplace(self):
        print('-'*50)
        cnt = len(self.res_pos)
        if self.res_pos is None or cnt == 0:
            return
        try:

            x, y = self.res_pos[self.focus_pos]
            text = self.find_widget.line_edit2.text()
            self.data[x][y] = text
            print(self.data[x][y])
        except Exception as e:
            print(e)

    def onClickReplaceAll(self):
        pass
    #设置变量
    def triggeredSetting(self):
        # 设置变量窗口
        var_list = self.data[0] if self.data[0][0]!='' else self.data[0][1:]
        self.dialog = VariableSettingWindow.VariableSettingWindowDemo(var_list)
        self.dialog.signal.sender.connect(self.getVarList)
        self.dialog.show()

    def getVarList(self,lst):
        self.var_list = lst