PyQt5从入门到实践系列-28-打造属于你的PyQt5多文档GUI体验!!

1-PyQt5多文档设计概念

PyQt5多文档界面,MDI(Multiple Document Interface)允许用户在同一应用程序窗口中打开和管理多个窗口文档。比较典型的多文档界面就比如我们常用的办公三件套:Word,Excel,PowerPoint等。其中每个文档通常是一个独立的子窗口,可以包含不同的内容,例如文本、图形或其它应用程序数据。

2-PyQt5多文档文本编辑器设计

2.1 Document UI文件设计

      新建-widget-拖拽一个文本编辑控件在窗口中,设计好布局即可。

图片

Document其实就是在MainWindow 主窗口运行时的一个个文档,因此,从面向对象的角度设计,该文档应该有自己的一些方法属性,比如:字体颜色、字体大小、文本居中、等。

def get_Text(self):
    return self.ui.plainTextEdit.toPlainText()

def textPaste(self):
    self.ui.plainTextEdit.paste()
    
def textSetFont(self):
    iniFont=self.ui.plainTextEdit.font()
    font,OK=QFontDialog.getFont(iniFont)
    if (OK):
       self.ui.plainTextEdit.setFont(font)
    
def toggleBold(self):
    cursor = self.ui.plainTextEdit.textCursor()
    current_format = cursor.charFormat()
    char_format = QTextCharFormat()
    char_format.setFontWeight(QFont.Bold if current_format.fontWeight() == QFont.Normal else QFont.Normal)
    cursor.mergeCharFormat(char_format)
    
def toggleItalic(self):
    cursor = self.ui.plainTextEdit.textCursor()
    current_format = cursor.charFormat()
    char_format = QTextCharFormat()
    char_format.setFontItalic(not current_format.fontItalic())
    cursor.mergeCharFormat(char_format)
    
def toggleD(self):
    cursor = self.ui.plainTextEdit.textCursor()
    current_format = cursor.charFormat()
    char_format = QTextCharFormat()
    char_format.setFontStrikeOut(not current_format.fontStrikeOut())
    cursor.mergeCharFormat(char_format)

def toggleUnder(self):
    cursor = self.ui.plainTextEdit.textCursor()
    current_format = cursor.charFormat()
    char_format = QTextCharFormat()
    char_format.setFontUnderline(not current_format.fontUnderline())
    cursor.mergeCharFormat(char_format)

def toggleCenter(self):
    cursor = self.ui.plainTextEdit.textCursor()
    current_format = cursor.blockFormat()
    block_format = QTextBlockFormat()
    block_format.setAlignment(Qt.AlignCenter)
    cursor.mergeBlockFormat(block_format)

def toggleLeft(self):
    cursor = self.ui.plainTextEdit.textCursor()
    current_format = cursor.blockFormat()
    block_format = QTextBlockFormat()
    block_format.setAlignment(Qt.AlignLeft)
    cursor.mergeBlockFormat(block_format)

def toggleRight(self):
    cursor = self.ui.plainTextEdit.textCursor()
    current_format = cursor.blockFormat()
    block_format = QTextBlockFormat()
    block_format.setAlignment(Qt.AlignRight)
    cursor.mergeBlockFormat(block_format)

def toggleJustify(self):
    cursor = self.ui.plainTextEdit.textCursor()
    current_format = cursor.blockFormat()
    block_format = QTextBlockFormat()
    block_format.setAlignment(Qt.AlignJustify)
    cursor.mergeBlockFormat(block_format)

def setTextColor(self):
    color= QColorDialog.getColor()
    if color.isValid():
        cursor = self.ui.plainTextEdit.textCursor()
        char_format = QTextCharFormat()
        char_format.setForeground(color)
        cursor.mergeCharFormat(char_format)

def selectAll(self):
    self.ui.plainTextEdit.selectAll()

def re_do(self):
    self.ui.plainTextEdit.redo()

def un_do(self):
    self.ui.plainTextEdit.undo()
def loadFile(self, file_name):  ##打开文件
  f=codecs.open(file_name,encoding='utf-8')
  try:
    for line in f: #每次读取一行
    self.ui.TextEdit.append(line.strip())
  finally:
    f.close()

2.2 MainWindow UI文件设计

      工具栏,菜单栏实现文件打开、新建、保存、另存为、字体样式等。QAction的相关设计请看前期【PyQt5从入门到精通系列02-布局(数据展示GUI小项目)】。此处,还需放置一个关键的控件:QMdiArea。直接在主窗口工作区拖拽放置,设置布局即可。

QMdiArea常用方法

  • addSubWindow():将给定的 QWidget 添加为子窗口,并返回对应的 QMdiSubWindow 对象。

  • cascadeSubWindows():以级联的方式排列所有子窗口。

  • tileSubWindows():以平铺的方式排列所有子窗口。

  • closeActiveSubWindow():关闭当前活动的子窗口。

  • subWindowList():返回子窗口的列表,可以按照 CreationOrder 或 StackingOrder 的顺序排列。

@pyqtSlot() #新建文档
def on_new_add_action_triggered(self):
    #实例化一个Document对象
    Doc = QDocument(self)
    #将该Document对象添加至MDI
    self.ui.mdiArea.addSubWindow(Doc)
    Doc.show()

@pyqtSlot()
#打开已经存在的文档
def on_open_file_action_triggered(self):
    current_path = os.getcwd() # 获取当前路径
    file_name, filter = QFileDialog.getOpenFileName(self, "打开一个文件", curPath,
                                                "文本文件(*.cpp *.h *.py);;所有文件(*.*)")
    if (file_name == ""):
        return
    formDoc = QDocument(self)
    self.ui.mdiArea.addSubWindow(formDoc)
    formDoc.loadFile(filename)
    formDoc.show()

def on_save_as_action_triggered(self):
    # 获取当前活跃文档的文本编辑控件
    active_subwindow = self.ui.mdiArea.activeSubWindow()
    if active_subwindow:
        text_edit = active_subwindow.widget()
        # 打开文件对话框,获取用户选择的保存路径
        document_path, _ = QFileDialog.getSaveFileName(self, 'Save As', '', 'Text Files (*.txt);;All Files (*)')
        if document_path:
            # 保存文档内容到指定路径
            with open(document_path, 'w',encoding="utf-8") as file:
                file.write(text_edit.get_Text())
                # 将文件路径保存到子窗口的属性中
                active_subwindow.setProperty('FilePath', document_path)

# 关闭全部
@pyqtSlot()
def on_action_4_triggered(self):
    self.ui.mdiArea.closeAllSubWindows()

@pyqtSlot(bool) #MDI模式
def on_actionMDI_triggered(self, checked):
    if checked: # Tab多页显示模式
        self.ui.mdiArea.setViewMode(QMdiArea.TabbedView) # Tab多页显示模式
        self.ui.mdiArea.setTabsClosable(True) # 页面可关闭
        self.ui.action_2.setEnabled(False)
        self.ui.action.setEnabled(False)
    else: # 子窗口模式
        self.ui.mdiArea.setViewMode(QMdiArea.SubWindowView) # 子窗口模式
        self.ui.action_2.setEnabled(True)
        self.ui.action.setEnabled(True)

@pyqtSlot() #级联展开
def on_action_2_triggered(self):
    self.ui.mdiArea.cascadeSubWindows()

@pyqtSlot() #平铺展开
def on_action_triggered(self):
    self.ui.mdiArea.tileSubWindows()

@pyqtSlot() #剪切操作-需要在Document.py中实现text_edit的textCut
def on_actEdit_Cut_triggered(self):
    formDoc = self.ui.mdiArea.activeSubWindow().widget()
    formDoc.textCut()

@pyqtSlot() #复制文本,同上
def on_copy_action_triggered(self):
    formDoc = self.ui.mdiArea.activeSubWindow().widget()
    formDoc.textCopy()

@pyqtSlot() #Paste操作,同上
def on_paste_action_triggered(self):
    formDoc = self.ui.mdiArea.activeSubWindow().widget()
    formDoc.textPaste()

@pyqtSlot() #字体设置,同上
def on_actEdit_Font_triggered(self):
    formDoc = self.ui.mdiArea.activeSubWindow().widget()
    formDoc.textSetFont()

@pyqtSlot()
def on_bold_action_triggered(self):
    formDoc = self.ui.mdiArea.activeSubWindow().widget()
    formDoc.toggleBold()

@pyqtSlot()
def on_Iter_action_triggered(self):
    formDoc = self.ui.mdiArea.activeSubWindow().widget()
    formDoc.toggleItalic()

@pyqtSlot()
def on_delete_action_triggered(self):
    formDoc = self.ui.mdiArea.activeSubWindow().widget()
    formDoc.toggleD()

@pyqtSlot()
def on_under_action_triggered(self):
    formDoc = self.ui.mdiArea.activeSubWindow().widget()
    formDoc.toggleUnder()

@pyqtSlot()
def on_centor_action_triggered(self):
    formDoc = self.ui.mdiArea.activeSubWindow().widget()
    formDoc.toggleCenter()

@pyqtSlot()
def on_left_action_triggered(self):
    formDoc = self.ui.mdiArea.activeSubWindow().widget()
    formDoc.toggleLeft()

@pyqtSlot()
def on_right_action_triggered(self):
    formDoc = self.ui.mdiArea.activeSubWindow().widget()
    formDoc.toggleRight()

@pyqtSlot()
def on_ld_action_triggered(self):
    formDoc = self.ui.mdiArea.activeSubWindow().widget()
    formDoc.toggleJustify()

def changeTextColor(self):
    active_subwindow = self.ui.mdiArea.activeSubWindow()
    if active_subwindow:
        text_edit = active_subwindow.widget()
        text_edit.setTextColor()

def on_select_all_action_triggered(self):
    active_subwindow = self.ui.mdiArea.activeSubWindow()
    if active_subwindow:
        text_edit = active_subwindow.widget()
        text_edit.selectAll()

def on_redo_action_triggered(self):
    active_subwindow = self.ui.mdiArea.activeSubWindow()
    if active_subwindow:
        text_edit = active_subwindow.widget()
        text_edit.re_do()

def on_recover_action_triggered(self):
    active_subwindow = self.ui.mdiArea.activeSubWindow()
    if active_subwindow:
        text_edit = active_subwindow.widget()
        text_edit.un_do()

3-PyQt5多文档文本编辑器效果展示

图片

图片

图片

图片

图片

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值