gpt4 book ai didi

c++ - MDI 窗口和 QSignalMapper 基础知识

转载 作者:行者123 更新时间:2023-11-30 01:25:14 25 4
gpt4 key购买 nike

首先,我很抱歉这个看起来很夸张的问题,但事实并非如此。我正在阅读 Foundation of qt development 一书,在阅读第四章时,作者通过展示这个例子讲述了 MDI 窗口的基础知识:

MdiWindow::MdiWindow( QWidget *parent ) : QMainWindow( parent ) {
setWindowTitle( tr( "MDI" ) );
QWorkspace* workspace = new QWorkspace;
setCentralWidget( workspace );
connect( workspace, SIGNAL(windowActivated(QWidget *)), this, SLOT(enableActions()));
QSignalMapper* mapper = new QSignalMapper( this );

//my problem is in this line
connect( mapper, SIGNAL(mapped(QWidget*)), workspace, SLOT(setActiveWindow(QWidget*)) );

createActions();
createMenus();
createToolbars();
statusBar()->showMessage( tr("Done") );
enableActions();
}

他的这一段解释完全让我看不懂(是我还是其他人也有理解问题?):

Next, a signal mapping object called QSignalMapper is created and connected. A signal mapper is used to tie the source of the signal to an argument of another signal. In this example, the action of the menu item corresponding to each window in the Window menu is tied to the actual document window. The actions are in turn connected to mapper. When the triggered signal is emitted by the action, the sending action has been associated with the QWidget* of the corresponding document window. This pointer is used as the argument in the mapped(QWidget*) signal emitted by the signal mapping object.

我的问题:在上面的示例中,我仍然不明白什么是信号映射器类、它是如何使用的以及它的功能是什么?。谁能用简单的术语解释上面的段落?如果你能用简单的例子教我 mapper 类的基础知识,那就太棒了?可能是外行人的说法?

P.S :一个困惑是当我们有 MDI 窗口时,进行菜单更改(尽管操作被禁用/启用)例如假设对于一个特定的文档我们有菜单“文件/关闭”和其他文档我们有“文件/重映射器”?

最佳答案

QSignalMapper 用于重新发射带有可选参数的信号。换句话说(来自 documentation ):

This class collects a set of parameterless signals, and re-emits them with integer, string or widget parameters corresponding to the object that sent the signal.

一个很好的例子(也来自文档 - 看看它)设置如下:

Suppose we want to create a custom widget that contains a group of buttons (like a tool palette). One approach is to connect each button's clicked() signal to its own custom slot; but in this example we want to connect all the buttons to a single slot and parameterize the slot by the button that was clicked.

假设您将许多按钮封装在一个类中,比如 ButtonWidget,带有自定义信号 void clicked(const QString &text)。这是定义:

class ButtonWidget : public QWidget {
Q_OBJECT

public:
ButtonWidget(QStringList texts, QWidget *parent = 0);

signals:
void clicked(const QString &text);

private:
QSignalMapper *signalMapper;
};

然后可以像下面这样定义构造函数:

ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)
: QWidget(parent)
{
signalMapper = new QSignalMapper(this);

QGridLayout *gridLayout = new QGridLayout;
for (int i = 0; i < texts.size(); ++i) {
QPushButton *button = new QPushButton(texts[i]);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, texts[i]);
gridLayout->addWidget(button, i / 3, i % 3);
}

connect(signalMapper, SIGNAL(mapped(const QString &)),
this, SIGNAL(clicked(const QString &)));

setLayout(gridLayout);
}

那么这里发生了什么?我们构建了一个网格布局和类型为 QPushButton 的按钮。其中每一个的 clicked() 信号都连接到信号映射器。

使用 QSignalMapper 的力量之一是您可以将参数传递给重新发射的信号。在我们的示例中,每个按钮都应发出不同的文本(由于信号的定义),因此我们使用 setMapping() 方法进行设置。

现在剩下要做的就是将信号映射器映射到我们类的信号:

connect(signalMapper, SIGNAL(mapped(const QString &)),
this, SIGNAL(clicked(const QString &)));

假设我们有一个名为 TestClass 的测试类,那么可以这样使用 ButtonWidget:

TestClass::TestClass() {
widget = new ButtonWidget(QStringList() << "Foo" << "Bar");
connect(widget, SIGNAL(clicked(const QString &)),
this, SLOT(onButtonClicked(const QString &)));
}

void TestClass::onButtonClicked(const QString &btnText) {
if (btnText == "Foo") {
// Do stuff.
}
else {
// Or something else.
}
}

通过以这种方式使用信号映射器,您不必声明和管理所有按钮及其点击信号,只需一个信号 pr。 ButtonWidget.

最重要的是,信号映射器非常适合捆绑多个信号,您甚至可以在它重新发射时设置参数。我希望这能让您对 QSignalMapper 的用法有一些直觉。


您的示例代码

解释(您的“para”)指出所有操作都单独映射到特定的 QWidget*。当触发一个 Action 时,其各自的 QWidget* 将被传递到 workspace 的插槽 QWorkspace::setActiveWindow(QWidget*) 中,这反过来会激活小部件。

另请注意,从操作到小部件的映射必须发生在代码中的某个位置。我假设它可能是在 createActions()enableActions() 中完成的。

关于c++ - MDI 窗口和 QSignalMapper 基础知识,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12652356/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com