在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文件中的信号。任何提示?
答案 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(); });
优点:
缺点: