代码之家  ›  专栏  ›  技术社区  ›  Bklyn

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

  •  3
  • Bklyn  · 技术社区  · 15 年前

    有什么方法可以把参数绑定到slots 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 slot,它将列索引作为参数:

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

    这些都能做到吗?

    4 回复  |  直到 12 年前
        1
  •  4
  •   Reed Hedges    15 年前

    Afaik的唯一方法是创建一个qSignalMapper对象来执行此操作。这就像一个额外的间接级别,可以用来生成一个提供列索引的新信号。这是一个有点笨拙的时间,你可以结束与许多qsignalmapper对象一直挂在周围,但似乎是目前最好的方式。(理想情况下,imo,您可以只提供任何值,例如列index to connect(),这些值将作为参数传递到槽中,但您不能。)

        2
  •  6
  •   Kaleb Pederson    15 年前

    LibQxt 通过qxtBoundFunction和qxtMetaObject实现这一点(前者不显示在 documentation 出于某种原因)。它是一个开放源码项目,因此如果您对实现感兴趣,可以获取源代码。它使用以下语法:

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

    LBQXT 还有一些其他非常有用的功能,比如 emit signals over a QIODevice 如网络连接。

        3
  •  6
  •   Ofir Farchy seyf    12 年前

    你不能用 setData 功能 QAction ?

    void MyWindow::contextMenuEvent (QContextMenuEvent* event)
    {
        m_column = view->columnAt (event->x());
        QMenu menu;
        QAction * action = menu.addAction (tr ("Hide Column"), this, SLOT (hideColumn ()));
        action->setData(QVariant(hideColumn));
    }
    
    void hideColumn()
    {
        const QAction * action = qobject_cast<const QAction *>(this->sender());
        assert(action);
    
        int hide_column = action->data().value<int>();
        this->view->setColumnHidden (m_column, true);
    }
    
        4
  •  3
  •   Robert Knight    12 年前

    正如上面的注释中所提到的,在qt 5中,这更容易,因为您可以将信号直接连接到函数,例如std::tr1::bind()或boost::bind()。对于Qt4,有许多适配器库。卡莱布提到了libqxt。我有一个在 https://github.com/robertknight/qt-signal-tools