问:调整信号/绑定参数到插槽?

时间:2009-05-07 17:11:03

标签: c++ qt boost

有没有办法将参数绑定到插槽ala boost::bind

这是一个例子。我有一个带树视图的窗口,我想允许用户从上下文菜单中隐藏一列。我最终做了类似的事情:

void MyWindow::contextMenuEvent (QContextMenuEvent* event) {
   m_column = view->columnAt (event->x());
   QMenu menu;
   menu.addAction (tr ("Hide Column"), this, SLOT (hideColumn ()));
   // .. run the menu, etc
}

我需要捕获激活上下文菜单的列的索引,并将其存储在我的窗口hideColumn插槽使用的成员变量中:

void MyWindow::hideColumn () {
    view->setColumnHidden (m_column, true);
}

我真正喜欢的是能够在创建菜单时将列号绑定到我的插槽,所以我不需要这个成员变量。基本上Qt相当于:

menu.addAction (tr ("Hide Column"),
                boost::bind (&MyWindow::hideColumn, this,
                             event->columnAt (event->x()));

甚至更好地调整QAction::triggered信号并将其附加到QTreeView::hideColumn插槽,该插槽将列索引作为参数:

menu.addAction (tr ("Hide Column"),
                boost::bind (&QTreeView::hideColumn, view,
                             event->columnAt (event->x())));

这有可能吗?

4 个答案:

答案 0 :(得分:6)

LibQxt通过QxtBoundFunction和QxtMetaObject使这成为可能(前者由于某种原因未出现在他们的documentation中)。这是一个开源项目,如果您对实现感兴趣,可以获取源代码。它使用以下语法:

connect(
    button,
    SIGNAL(clicked()),
    QxtMetaObject::bind(
        lineEdit,
        SLOT(setText(QString)),
        Q_ARG(QString, "Hello World!)
        )
    );

LibQxt还有一些非常有用的功能,例如emit signals over a QIODevice的功能,例如网络连接。

答案 1 :(得分:6)

您是否可以使用setData的<{1}}功能?

QAction

答案 2 :(得分:4)

AFAIK唯一的方法是创建一个QSignalMapper对象来执行此操作。它就像一个额外的间接级别,可用于生成提供列索引的新信号。这是一个有点笨拙的IME,你最终会有很多QSignalMapper对象一直闲逛,但这似乎是目前最好的方式。 (理想情况下,IMO,您可以只提供任何值,例如connect()的列索引,它将作为参数传递给插槽,但您不能。)

答案 3 :(得分:3)

正如上面的评论中所提到的,这在Qt 5中要容易得多,因为您可以将信号直接连接到仿函数,例如std :: tr1 :: bind()或boost :: bind()的结果。对于Qt 4,有许多适配器库。 Kaleb提到了LibQxt。我在https://github.com/robertknight/qt-signal-tools

有一个