Qt:如何使用 QSignalMapper 为非标准按钮实现 QDialogBu​​ttonBox ?

Posted

技术标签:

【中文标题】Qt:如何使用 QSignalMapper 为非标准按钮实现 QDialogBu​​ttonBox ?【英文标题】:Qt: How to implement QDialogButtonBox with QSignalMapper for non-standard button ?? 【发布时间】:2013-04-29 08:21:04 【问题描述】:

我有一个带有所有标准按钮和非标准按钮的 QDialogBu​​ttonBox(添加 QPushbutton 以创建非标准按钮)。

我可以为非标准按钮单独实现 SignalMapper。但在这种情况下,我必须添加 2 个插槽(用于 QDialogBu​​ttonBox 标准按钮的插槽和用于非标准按钮的插槽)。

我需要为标准按钮和非标准按钮实现带有公共插槽的 QSignalMapper。

有人可以指导我吗?

【问题讨论】:

【参考方案1】:

您不需要将QSignalMapperQDialogButtonBox 一起使用。

QSignalMapper 用于将多个信号连接到单个插槽,QDialogButtonBox 已经为所有按钮发出了单个信号:clicked(QAbstractButton*)

您可以简单地使用映射(QMapstd::map)或通过动态属性为按钮赋值:

enum  MyRole1 = 1, MyRole2 ; // starting at 1 because an unset property would return 0
...
userButton−>setProperty("ActionRole", MyRole1); // a cast to int might be needed here
buttonBox->addButton(userButton, QDialogButtonBox::ActionRole);

connect(this, SIGNAL(clicked(QAbstractButton*)), SLOT(dialogButtonClicked(QAbstractButton *button)));

在槽中,你会从信号传递的参数中取回值:

void MyClass::dialogButtonClicked(QAbstractButton *button) 
    StandardButton standardButton = buttonBox−>standardButton(button);
    switch(standardButton) 
    // Standard buttons:
    case QDialogButtonBox::Ok: 
        ... 
        break;
    case QDialogButtonBox::Abort: 
        ...
        break;

    // Non-standard buttons:
    case QDialogButtonBox::NoButton: 
       int actionRole = button->property("ActionRole").toInt();
       switch(actionRole) 
       case MyRole1: 
           ...
           break;
       case MyRole2: 
           ...
           break;
      default:
           // shouldn't happen
           break; 
       

    
 

【讨论】:

【参考方案2】:

QSignalMapper 可以映射一个 QObject 和一个整数。因此,您可以将 non-standardButton 与其角色映射并创建一个接收参数角色的插槽:

例如:

void Widget::initMap() 
     QPushButton* buttonReset = new QPushButton( "Reset" );
     signalMapper = new QSignalMapper(this);
     connect(buttonReset, SIGNAL(clicked()), signalMapper, SLOT(map()));
     signalMapper->setMapping(button, QDialogButtonBox::ResetRole);
     connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(slot(int)));


void Widget::slot( int role) 
    if ( role == QDialogButtonBox::ResetRole ) 
        reset();
     else if ( QDialogButtonBox::Apply ) 
        apply();
    

【讨论】:

感谢您的回答。你能告诉我上面的例子是如何声明“buttonReset”的吗?通常我将标准按钮添加为: ui->buttonBox->addButton(QDialogBu​​ttonBox::Reset);和非标准按钮: userButton = new QPushButton(tr(getButtonText(button))); ui->buttonBox->addButton(userButton, QDialogBu​​ttonBox::ActionRole); 我认为 buttonReset 是像 QPushButton 一样的非标准按钮。 (我已经更新了我的示例)。

以上是关于Qt:如何使用 QSignalMapper 为非标准按钮实现 QDialogBu​​ttonBox ?的主要内容,如果未能解决你的问题,请参考以下文章

Qt 插槽未被调用

使用 QSignalMapper

QSignalMapper类处理多信号关联同一个槽的方法

如何在 Qt 中模拟消息总线?

QtApplets-QSignalMapper使用

Qt 信号映射:编辑发射器对象