我基本上有多个事件信号,我想连接到同一个插槽.我想知道的是如何将基于字符串的参数传递到同一个插槽,以便插槽知道这个信号来自哪个.一种替代方案是制作与信号一样多的插槽,然后以1:1的方式连接它们,但考虑到所有处理的代码非常相似,这是有效的.我尝试过这样做,但是我遇到了一些错误:
connect(selecter1,SIGNAL(selected(QString)),this,SLOT(backgroundTypeChoiceMade(QString)));
connect(button1,SIGNAL(clicked()),this,SLOT(backgroundTypeChoiceMade("button1")));
connect(button2,SIGNAL(clicked()),this,SLOT(backgroundTypeChoiceMade("button2")));
Run Code Online (Sandbox Code Playgroud)
该错误与我在最后2个命令中传递的参数有关..并且backgroundTypeChoiceMade声明如下:
void backgroundTypeChoiceMade(QString);
Run Code Online (Sandbox Code Playgroud)
有人能告诉我上面代码中的错误是什么吗?
四种方法.一个人不好意思.
QSignalMapper.工作,但使代码混乱.sender()-相比.可以处理动态发件人,但仍然有点难看.特别是当您使用少量信号和发送方类型以及动态生成发件人时,将发件人子类化是最干净的方式.这使您可以重载现有信号以包含所需的任何参数.
现在,连接信号和插槽就可以了:
Keypad::Keypad(QWidget *parent) : QWidget(parent)
{
for (int i = 0; i < 10; ++i)
{
// KeypadButton keeps track of the identifier you give it
buttons[i] = new KeypadButton(i, this);
// And passes it as a signal parameter. Booyah.
connect(buttons[i], SIGNAL(clicked(int)), this, SIGNAL(digitClicked(int)));
}
createLayout();
}
void Keypad::digitClicked(int digit)
{
// The slot can find the clicked button with ease:
dial(button[i]); // or whatever
//...
}
Run Code Online (Sandbox Code Playgroud)
并且额外的代码在子类中是不可见的,你永远不会再触摸它.
有关子类化的示例实现,请参阅http://doc.qt.digia.com/qq/qq10-signalmapper.html#thesubclassapproachQPushButton以发出clicked(int)信号.还讨论了所有四种方法 - 命名槽("普通解决方案"),sender(),子类化和信号映射器.
警告:显然最适合少量的发件人类型.但通常情况就是如此.在那种情况下,这是值得的.
使用单独的插槽有什么效率低?如果插槽处理程序中存在共性,则将其移动到函数中,例如扩展ereOn的示例:
void YourClass::YourClass() :
m_button1(new QPushButton()),
m_button2(new QPushButton())
{
connect(m_button1, SIGNAL(clicked()), this, SLOT(yourSlot1()));
connect(m_button2, SIGNAL(clicked()), this, SLOT(yourSlot2()));
}
void YourClass::common(int n)
{
}
void YourClass::yourSlot1()
{
common (1);
}
void YourClass::yourSlot2()
{
common (2);
}
Run Code Online (Sandbox Code Playgroud)
您不能传递常量,connect()因为有效参数是在执行时而不是编译时推导的。
然而,虽然这违反了OO原则,但您可以使用QObject::sender()which给出指向发射器的指针QObject。
下面的例子:
void YourClass::YourClass() :
m_button1(new QPushButton()),
m_button2(new QPushButton())
{
connect(m_button1, SIGNAL(clicked()), this, SLOT(yourSlot()));
connect(m_button2, SIGNAL(clicked()), this, SLOT(yourSlot()));
}
void YourClass::yourSlot()
{
if ((QPushButton* button = dynamic_cast<QPushButton*>(sender()))
{
// Now button points to a QPushButton* that you can compare with the pointers you already have
if (button == m_button1)
{
// Whatever
} else
if (button == m_button2)
{
// Whatever
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您有很多按钮,您还可以通过为每个按钮提供标识符来使用QSignalMapper 。
| 归档时间: |
|
| 查看次数: |
4609 次 |
| 最近记录: |