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

时间:2013-04-29 08:21:04

标签: qt

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

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

我需要使用标准按钮和非标准按钮的公共插槽来实现QSignalMapper。

任何人都可以指导我吗?

2 个答案:

答案 0 :(得分:7)

您不应该将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; 
       }

    }
} 

答案 1 :(得分:0)

QSignalMapper可以映射QObject和整数。因此,您可以将非标准按钮映射到其角色,并创建一个插槽,该参数将参数作为角色:

例如:

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();
    }
}