jah*_*aho 11 c++ user-interface qt class-design signals-slots
假设我有一个带有滑块的主窗口和一个窗口内的窗口小部件,其方法称为setValue(int)
.每次滑块的值发生变化时,我都想调用此方法.
以下两种实现方式之间是否存在实际差异:
void MainWindow::on_slider_valueChanged(int value)
{
ui->widget->setValue(value);
}
Run Code Online (Sandbox Code Playgroud)
// somewhere in constructor
connect(ui->slider, SIGNAL(valueChanged(int)), ui->widget, SLOT(setValue(int)));
Run Code Online (Sandbox Code Playgroud)
对我来说,第一种方法看起来更好,因为它可能避免与信号和插槽机制相关的一些开销,并且,如果需要它,允许我value
在发送之前处理widget
它.
是否存在第二种解决方案更好的情况?
两种方法都使用信号槽连接.在第一种情况下,通过connect
调用来进行QMetaObject::connectSlotsByName()
调用setupUi
.在第二种情况下,你明确地称connect
自己为.
此外,在使用C++ 11时,Qt5中不需要第一种方法.您可以修改lambda中的值:
QObject::connect(ui->slider, &QAbstractSlider::valueChanged,
[this](int val){ ui->widget->setValue(val*2); });
Run Code Online (Sandbox Code Playgroud)
为了防止删除ui->widget
,您应该使用QPointer
:
class MyWindow : public QMainWindow {
QPointer<QAbstractSlider> m_widget;
...
public:
MyWindow(QWidget * parent = 0) : QMainWindow(parent) {
...
setupUi(this);
m_widget = ui->widget;
QObject::connect(ui->slider, &QAbstractSlider::valueChanged,
[this](int val)
{
if (!m_widget.isNull()) m_widget->setValue(val*2);
});
Run Code Online (Sandbox Code Playgroud)
在这个答案中量化了信号槽连接的开销.
在您的示例中,使用信号而不是直接调用的主要区别是允许多个侦听器。
如果你直接调用你的 widget setValue()
,那么只有那个 widget 会收到 C++ 信号。
如果您使用 Qt 信号,现在任何其他对象都可以连接以在事件发生时接收该事件。
如果您没有预见到任何其他对象想要通过信号接收值,我不会为此烦恼。直接调用肯定要快得多(3 到 6 个 CPU 指令,而不是处理字符串来查找接收者!),但正如 Paranaix 提到的,在 GUI 中这可能不是什么大问题(尽管在这种情况下它可能会变成如果您在移动滑块时发送所有这些信号,则在旧计算机上会出现问题。)
归档时间: |
|
查看次数: |
7403 次 |
最近记录: |