Qt“连接”语法很长。是否有任何技巧可以缩短它?

时间:2009-12-26 10:39:32

标签: qt

在C#中,为了将信号连接到插槽(委托给方法),我所做的就是:

first.signal += second.slot

但在Qt中它是:

connect( & first, SIGNAL( signal( int, int, QString ) ), & second, SLOT( slot( int, int, QSTring ) ) );

这个被计算得很短,通常它们会产生2-3行。当然我完全理解Qt只模拟.h文件,而对于.cpp,它们必然会受到标准语法的限制,但是有什么技巧/方法可以使信号插槽连接更短一些吗?我知道通过给插槽提供特殊名称来自动将信号连接到插槽,但这仅适用于.ui文件中的信号。任何提示?

7 个答案:

答案 0 :(得分:6)

  

我知道通过为插槽提供特殊名称来自动将信号连接到插槽,但这仅适用于.ui文件中的信号

该方法可以在.ui文件之外使用,您可以在任何地方调用QMetaObject::connectSlotsByName

答案 1 :(得分:3)

如果您发现那么长且重复,您可以使用宏来使语法更轻松。例如:

#define S_i_i(x) x(int, int, QString)
#define CONNECT(sx,x,tx,sy,y,ty) connect(&x, SIGNAL(tx(sx)), &y, SLOT(ty(sy)))

CONNECT(signal, first, S_i_i, slot, second, S_i_i)

缺点是除非您仔细选择宏,否则您的代码将失去其他人的可读性。

答案 2 :(得分:3)

如果您正在将不同对象中的信号连接到 this 对象中的插槽,则可以执行快捷方式,并使用此方法:

connect( & first, SIGNAL( signal( int, int, QString ) ), SLOT( slot( int, int, QSTring ) ) );

而不是:

connect( & first, SIGNAL( signal( int, int, QString ) ), & second, SLOT( slot( int, int, QSTring ) ) );

删除了一点连接。我相信还有其他快捷方式。但是,您的一般观点是有效的,并且主要是Qt如何执行其信号/插槽机制的副作用。如果你真的想在C ++中使用更简洁的语法,你可以查看Boost :: Signals或SigC ++库,它们也提供信号/插槽机制。但请注意语法冲突。

答案 3 :(得分:1)

我个人认为不是那么糟糕。您只需为每个信号/插槽编写一次,大多数情况下您不必在之后触摸它。

我发现最接近的事情就是使用boost :: bind / function和信号/插槽机制。它不能直接回答您的问题,但它是相关的,您可以使用它。你可以阅读它here

答案 4 :(得分:1)

一个技巧是使用QtCreator作为编辑器,因为它允许您在键入时从下拉列表中选择信号和插槽。

一个看似无关的反映是Qt努力拥有一个相当冗长的API,因为它更容易阅读(并且在写作时要记住)。因此,他们避免缩写并写出他们的意思:QAbstractItemModel,setWindowTitle等。不是QAbstItModel,setWinTit等。更多的输入,更少的误解和链接器错误(缺少符号)

答案 5 :(得分:0)

几年后,我找到了一种可以缩短连接速度的解决方案。解决方案基于@WildSeal的答案并使用这个简单的宏:

#define QCON( a, b, c, d ) VERIFY( QObject::connect( a, SIGNAL(b), c, SLOT(d) ) )

所以,有问题的长码:

VERIFY( QObject::connect( first, SIGNAL(signal(int,int,QString)), second, SLOT(slot(int,int,QSTring)) ) );

将变得明显缩短:

QCON( first, signal(int,int,QString), second, slot(int,int,QString) );

欢迎任何意见和建议:)。我现在发现的唯一缺点是我需要一个单独的宏来连接SIGNAL和SIGNAL。但是因为这种操作很少见,所以我刚刚介绍了QCONS()并且它有一个技巧。

答案 6 :(得分:0)

支持Qt5和C ++ 11的编译器的另一种解决方案:

#define Q_CONNECT(sender, signal, receiver, slot) \
    QWidget::connect( \
        sender, &boost::remove_reference<boost::mpl::identity<decltype(*sender)>::type>::type::signal, \
        receiver, &boost::remove_reference<boost::mpl::identity<decltype(*receiver)>::type>::type::slot);

#define Q_CONNECT_LAMBDA(sender, signal, receiver) \
    QWidget::connect( \
    sender, &boost::remove_reference<boost::mpl::identity<decltype(*sender)>::type>::type::signal, \
    receiver);

请注意,仅对尚未处理以下内容的编译器(如VS2010)需要boost :: mpl :: identity:

decltype(expr)::member

用法示例:

Q_CONNECT(
    this, mySignalMethodName,
    &someHandler, handlerMethodName);

Q_CONNECT_LAMBDA(
    this, mySignalMethodName,
    [=]() { handlerCode(); });

优点:

  • 无需输入参数列表;
  • 无需明确复制类型信息;
  • 无需使用SIGNAL,SLOT,Q_SIGNAL,Q_SLOT宏中的任何一种;
  • 所有兼容性检查都是编译时。

缺点:

  • 不适用于重载方法。