如何通过Qt中的菜单锁定所有工具栏?

How to lock all toolbars via menu in Qt?

我正在试验 Qt Creator 和 Application Example

我想在工具栏菜单中添加一个可检查的菜单项,该菜单项显示为 "Lock toolbars",并且在检查时锁定所有工具栏的位置。我想这是一个很常见的功能。

我设法通过以下方式找到了一个锁定单条柱的命令:

toolBar->setMovable(false);

但我不知道如何锁定所有工具栏。

编辑

这个问题曾经包含有关工具栏上下文菜单而不是标准菜单的查询。由于我在其他地方得到了有关上下文菜单的答案,因此我将其从这个问题中删除了。

这是一个如何实现它的例子。首先,添加一个QAction and a QMenu;另外,声明你所有的工具栏都是私有的:

private:
    QMenu*     m_pLockMenu;

    QToolBar*  m_pFileToolBar;
    QToolBar*  m_pEditToolBar;
    QToolBar*  m_pHelpToolBar;

    QAction*   m_pLockAction;

此外,声明一个 slot,当操作被触发时,您将在其中管理工具栏的锁定:

public slots :
    void lockActionTriggered();

实施您的广告位。你只需要锁定所有的工具栏:

void lockActionTriggered()
{
    m_pFileToolBar->setMovable(false);
    m_pEditToolbar->setMovable(false);
    m_pHelpToolBar->setMovable(false);
}

现在,您只需在 .cpp 中声明您的主 window,并在其中添加菜单、工具栏和操作 :

QMainWindow* mainWindow = new QMainWindow();

m_pLockMenu = mainWindow->menuBar()->addMenu("Lock Toolbars");

m_pFileToolBar = mainWindow->addToolBar("File");
m_pEditToolBar = mainWindow->addToolBar("Edit");
m_pHelpToolBar = mainWindow->addToolBar("Help");

m_pLockAction = new QAction("Lock", this);

现在,将操作添加到菜单:

m_pLockMenu->addAction(m_pLockAction);

并将 QAction 的信号 triggered() 连接到您的插槽:

connect(m_pLockAction, SIGNAL(triggered()), this, SLOT(lockActionTriggered()));

别忘了 show() 你的主要 window :

mainWindow->show();

现在应该可以使用了!


编辑

您的代码必须如下所示:

mainwindow.h中:

class MainWindow : public QMainWindow
{

...

private:
    QMenu*     m_pLockMenu;

    QToolBar*  m_pFileToolBar;
    QToolBar*  m_pEditToolBar;
    QToolBar*  m_pHelpToolBar;

    QAction*   m_pLockAction;

public slots :
    void lockActionTriggered();
};

main.cpp:

int main(int argc, char *argv[])
{

    ...
    QApplication app(argc, argv);
    MainWindow window;
    window.show();

    app.exec();

}

mainwindow.cpp:

void MainWindow::createActions()
{
    m_pLockMenu = menuBar()->addMenu("Lock Toolbars");

    m_pFileToolBar = addToolBar("File");
    m_pEditToolBar = addToolBar("Edit");
    m_pHelpToolBar = addToolBar("Help");

    m_pLockAction = new QAction("Lock", this);

    m_pLockMenu->addAction(m_pLockAction);

    connect(m_pLockAction, SIGNAL(triggered()), this, SLOT(lockActionTriggered()));

    ...
}

void MainWindow::lockActionTriggered()
{
    m_pFileToolBar->setMovable(false);
    m_pEditToolbar->setMovable(false);
    m_pHelpToolBar->setMovable(false);
}

如果您有指向主窗口的指针,您可以简单地找到所有工具栏并遍历它们:

// in slot
for (auto *t: mainWindow->findChildren<QToolBar*>())
    t->setMovable(false);

或者,当您初始化 UI:

时,您可能希望将所有工具栏连接到单个切换操作
// in constructor
for (auto *t: this->findChildren<QToolBar*>())
    connect(action, &QAction::toggled, t, &QToolBar::setMovable);

一个具有灵活锁定选项的常见示例

# Created by BaiJiFeiLong@gmail.com at 2022/2/15 22:56
import typing

from PySide2 import QtWidgets, QtGui, QtCore


class Window(QtWidgets.QMainWindow):
    def createPopupMenu(self) -> QtWidgets.QMenu:
        menu = super().createPopupMenu()
        menu.addSeparator()
        toolBars: typing.Sequence[QtWidgets.QToolBar] = self.findChildren(QtWidgets.QToolBar)
        for toolbar in toolBars:
            if toolbar.rect().contains(toolbar.mapFromGlobal(QtGui.QCursor.pos())):
                title = "%s %s" % ("Lock" if toolbar.isMovable() else "Unlock", toolbar.windowTitle())
                menu.addAction(title, lambda toolbar=toolbar: toolbar.setMovable(not toolbar.isMovable()))
        menu.addSeparator()
        if any(x.isMovable() for x in toolBars):
            menu.addAction("Lock All", lambda: list(x.setMovable(False) for x in toolBars))
        if any(not x.isMovable() for x in toolBars):
            menu.addAction("Unlock All", lambda: list(x.setMovable(True) for x in toolBars))
        return menu


app = QtWidgets.QApplication()
window = Window()
window.setWindowTitle("Toolbar Example")
for i in range(1, 6):
    toolBar = window.addToolBar(f"ToolBar{i}")
    toolBar.setMovable(i % 2 == 0)
    toolBar.addWidget(QtWidgets.QPushButton(f"ToolBar {i}"))
label = QtWidgets.QLabel("Ready")
label.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
window.setCentralWidget(label)
window.resize(800, 600)
window.show()
app.exec_()