iT邦幫忙

2022 iThome 鐵人賽

DAY 30
0
Software Development

[Python QT] 玩玩 Pyside 的各種功能系列 第 30

【Day30】QHelpContentWidget + QToolBar 之說明視窗

  • 分享至 

  • xImage
  •  

有了可以參考的東西後, 要開始就簡單了
就按照一般說明視窗的出現方式, 先創個主視窗, 在主視窗按下"說明"後再跳出說明視窗
主視窗就拿我們之前的 ToolButton 的成果來修改吧
Icon 來源: Flaticon
主視窗程式碼

import sys
from PySide6.QtWidgets import *
from PySide6.QtCore import *
from PySide6.QtGui import *
from HelpContentWidget import Help

class MyWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.num = 0
        layout = QGridLayout()
        self.setLayout(layout)
        self.edit = QLineEdit()
        self.edit.setContextMenuPolicy(Qt.CustomContextMenu)
        self.edit.customContextMenuRequested.connect(self.rightClickMenu)
        layout.addWidget(self.edit, 1, 0, 2, 4)
        self.help = Help()
        self.help.setWindowIcon(QIcon("icon\\conversation.png"))
        self.help.setWindowTitle("說明")
        self.help.hide()

        self.tb = QToolButton(self)
        self.tb.setText("檔案")
        self.tb.setAutoRaise(True)
        self.tb.setStyleSheet("QToolButton::menu-indicator { image: None; }")
        self.tb.setCursor(Qt.PointingHandCursor)
        layout.addWidget(self.tb, 0, 0)
        self.editTB = QToolButton(self)
        self.editTB.setText("編輯")
        self.editTB.setAutoRaise(True)
        self.editTB.setStyleSheet("QToolButton::menu-indicator { image: None; }")
        self.editTB.setCursor(Qt.PointingHandCursor)
        layout.addWidget(self.editTB, 0, 1)
        self.helpTB = QToolButton(self)
        self.helpTB.setText("說明")
        self.helpTB.setAutoRaise(True)
        self.helpTB.setStyleSheet("QToolButton::menu-indicator { image: None; }")
        self.helpTB.setCursor(Qt.PointingHandCursor)
        self.helpTB.clicked.connect(self.openHelpWindow)
        layout.addWidget(self.helpTB, 0, 2)
        self.setupToolButton()

    def setupToolButton(self):
        self.setupFileToolButton()
        self.setupEditToolButton()

    def setupFileToolButton(self):
        menu = QMenu("Menu", self)
        menu.setCursor(Qt.PointingHandCursor)
        newMenu = QMenu("新文件", self)
        newMenu.setIcon(QIcon("icon\document.png"))
        doc = QAction(QIcon("icon\document (1).png"), "文件", self)
        useExample = QAction(QIcon("icon\edit-alt.png"), "使用範本", self)
        newMenu.addAction(doc)
        newMenu.addAction(useExample)
        open = QAction(QIcon("icon\_folder.png"), "開啟", self)
        open.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_O))
        open.setShortcutContext(Qt.ApplicationShortcut)
        makeCopy = QAction(QIcon("icon\duplicate.png"), "建立副本", self)
        rename = QAction(QIcon("icon\edit.png"), "重新命名", self)
        move = QAction(QIcon("icon\_book-arrow-right.png"), "移動", self)
        delete = QAction(QIcon("icon\\trash.png"), "移至垃圾桶", self)
        menu.addMenu(newMenu)
        menu.addAction(open)
        menu.addAction(makeCopy)
        menu.addSeparator()
        menu.addAction(rename)
        menu.addAction(move)
        menu.addAction(delete)

        self.tb.setMenu(menu)
        self.tb.setPopupMode(QToolButton.InstantPopup)

    def setupEditToolButton(self):
        self.editMenu = QMenu("Menu", self)
        self.editMenu.setCursor(Qt.PointingHandCursor)
        undo = QAction(QIcon("icon\\undo-alt.png"), "復原", self)
        undo.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Z))
        undo.setShortcutContext(Qt.ApplicationShortcut)
        undo.triggered.connect(self.edit.undo)
        redo = QAction(QIcon("icon\\redo-alt.png"), "取消復原", self)
        redo.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Y))
        redo.setShortcutContext(Qt.ApplicationShortcut)
        redo.triggered.connect(self.edit.redo)
        cut = QAction(QIcon("icon\\scissors.png"), "剪下", self)
        cut.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_X))
        cut.setShortcutContext(Qt.ApplicationShortcut)
        cut.triggered.connect(self.edit.cut)
        copy = QAction(QIcon("icon\\copy.png"), "複製", self)
        copy.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_C))
        copy.setShortcutContext(Qt.ApplicationShortcut)
        copy.triggered.connect(self.edit.copy)
        paste = QAction("貼上", self)
        paste.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_V))
        paste.setShortcutContext(Qt.ApplicationShortcut)
        paste.triggered.connect(self.edit.paste)
        delete = QAction(QIcon("icon\\trash.png"), "刪除", self)
        delete.triggered.connect(self.edit.backspace)
        selectAll = QAction("全選", self)
        selectAll.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_A))
        selectAll.setShortcutContext(Qt.ApplicationShortcut)
        selectAll.triggered.connect(self.edit.selectAll)
        self.editMenu.addAction(undo)
        self.editMenu.addAction(redo)
        self.editMenu.addSeparator()
        self.editMenu.addAction(cut)
        self.editMenu.addAction(copy)
        self.editMenu.addAction(paste)
        self.editMenu.addAction(delete)
        self.editMenu.addSeparator()
        self.editMenu.addAction(selectAll)

        self.editTB.setMenu(self.editMenu)
        self.editTB.setPopupMode(QToolButton.InstantPopup)

    def rightClickMenu(self):
        self.editMenu.popup (QCursor.pos())

    def openHelpWindow(self):
        self.help.show()

    def closeEvent(self, event):
        self.help.close()

if __name__ == "__main__":
    app = QApplication([])

    widget = MyWidget()
    widget.resize(300, 300)
    widget.show()

    sys.exit(app.exec())

因為我們參考的程式在主程式關閉後, 說明視窗也會關閉, 因此在這裡使用了 closeEvent
當主視窗 close 時, 把 help 也關閉
以下展示
main

接下來我們開始動工說明視窗
先把上方選單完成

import sys
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *

class Help(QMainWindow):
    def __init__(self):
        super().__init__()
        toolbar = QToolBar()
        toolbar.setFloatable(False)
        toolbar.setMovable(False)
        toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.addToolBar(toolbar)

        button_hide = QAction(QIcon("icon\\import.png"), "隱藏", self)
        button_back = QAction(QIcon("icon\\left-arrow.png"), "上一頁", self)
        button_print = QAction(QIcon("icon\\printer.png"), "列印", self)
        tb = QToolButton(self)
        tb.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        tb.setStyleSheet("QToolButton::menu-indicator { position: absolute; top: 0%; width: 10%;}")
        tb.setIcon(QIcon("icon\\drop-down-menu.png"))
        tb.setText("選項(O)")
        tb.setAutoRaise(True)
        tb.setPopupMode(QToolButton.InstantPopup)
        menu = QMenu("menu", self)
        hide = QAction("隱藏索引標籤(T)", self)
        menu.addAction(hide)
        tb.setMenu(menu)
        toolbar.addAction(button_hide)
        toolbar.addAction(button_back)
        toolbar.addAction(button_print)
        toolbar.addWidget(tb)
        
        self.resize(300, 300)

if __name__ == "__main__":
    app = QApplication([])
    QApplication.setApplicationName("說明")
    QApplication.setWindowIcon(QIcon("icon\\conversation.png"))
    table = Help()
    table.show()
    sys.exit(app.exec())

展示
https://ithelp.ithome.com.tw/upload/images/20221002/20151144Z79gZprMj1.png

這裡使用到了之前沒用過, 我自己也沒用過的 QToolBar, QToolBar 初始設定是可以讓使用者拉出主視窗, 也可以在主視窗內像 Windows 畫面上的工具列一樣自由地移到螢幕上下左右邊邊, 但在這裡不需要使用到, 因此透過

toolbar.setFloatable(False)
toolbar.setMovable(False)

關閉這兩個功能

有了工具欄後, 開始把內容物加進去
在這裡用到了 self.setCentralWidget() 根據官網上關於視窗的 Qt Main Window Framework 可以使用上面那句讓工具欄跟內容位置不會重疊
以下是沒有使用 setCentralWidget 的長相
https://ithelp.ithome.com.tw/upload/images/20221002/201511446gqb5hIzIS.png
可以看到工具欄跟 HelpContentWidget 的錨點(Anchor) 是一樣的, 因此後加的內容會蓋住早點加進視窗的內容

加上 setCentralWidget 後
https://ithelp.ithome.com.tw/upload/images/20221002/20151144Aux0mMoL3u.png

整個下方都是 HelpContentWidget 了
程式碼下收

import sys
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtHelp import *
from PySide6.QtCore import *

class Help(QMainWindow):
    def __init__(self):
        super().__init__()
        toolbar = QToolBar(self)
        self.test = QHelpContentWidget()
        self.setCentralWidget(self.test)
        toolbar.setFloatable(False)
        toolbar.setMovable(False)
        toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.addToolBar(toolbar)

        button_hide = QAction(QIcon("icon\\import.png"), "隱藏", self)
        button_back = QAction(QIcon("icon\\left-arrow.png"), "上一頁", self)
        button_print = QAction(QIcon("icon\\printer.png"), "列印", self)
        tb = QToolButton(self)
        tb.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        tb.setStyleSheet("QToolButton::menu-indicator { position: absolute; top: 0%; width: 10%;}")
        tb.setIcon(QIcon("icon\\drop-down-menu.png"))
        tb.setText("選項(O)")
        tb.setAutoRaise(True)
        tb.setPopupMode(QToolButton.InstantPopup)
        menu = QMenu("menu", self)
        hide = QAction("隱藏索引標籤(T)", self)
        menu.addAction(hide)
        tb.setMenu(menu)
        toolbar.addAction(button_hide)
        toolbar.addAction(button_back)
        toolbar.addAction(button_print)
        toolbar.addWidget(tb)
        self.resize(300, 300)

if __name__ == "__main__":
    app = QApplication([])
    QApplication.setApplicationName("說明")
    QApplication.setWindowIcon(QIcon("icon\\conversation.png"))
    table = Help()
    table.show()
    sys.exit(app.exec())

接下來因為我們參考的範例有分左右視窗 因此在這裡我們使用 QSplitter

import sys
from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtHelp import *
from PySide6.QtCore import *

class Help(QMainWindow):
    def __init__(self):
        super().__init__()
        toolbar = QToolBar(self)
        self.leftHelp = QHelpContentWidget()
        self.rightHelp = QHelpContentWidget()
        splitter = QSplitter(Qt.Horizontal)
        splitter.addWidget(self.leftHelp)
        splitter.addWidget(self.rightHelp)
        self.setCentralWidget(splitter)
        toolbar.setFloatable(False)
        toolbar.setMovable(False)
        toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        self.addToolBar(toolbar)

        button_hide = QAction(QIcon("icon\\import.png"), "隱藏", self)
        button_back = QAction(QIcon("icon\\left-arrow.png"), "上一頁", self)
        button_print = QAction(QIcon("icon\\printer.png"), "列印", self)
        tb = QToolButton(self)
        tb.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        tb.setStyleSheet("QToolButton::menu-indicator { position: absolute; top: 0%; width: 10%;}")
        tb.setIcon(QIcon("icon\\drop-down-menu.png"))
        tb.setText("選項(O)")
        tb.setAutoRaise(True)
        tb.setPopupMode(QToolButton.InstantPopup)
        menu = QMenu("menu", self)
        hide = QAction("隱藏索引標籤(T)", self)
        menu.addAction(hide)
        tb.setMenu(menu)
        toolbar.addAction(button_hide)
        toolbar.addAction(button_back)
        toolbar.addAction(button_print)
        toolbar.addWidget(tb)
        self.resize(300, 300)

if __name__ == "__main__":
    app = QApplication([])
    QApplication.setApplicationName("說明")
    QApplication.setWindowIcon(QIcon("icon\\conversation.png"))
    table = Help()
    table.show()
    sys.exit(app.exec())

展示
https://ithelp.ithome.com.tw/upload/images/20221002/201511445j3WEw7WfA.png


上一篇
【Day29】QHelpContentWidget
下一篇
【Day30】30 天心得
系列文
[Python QT] 玩玩 Pyside 的各種功能31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言