Qt. Можно ли использовать локальную переменную в Connect SLOT ()? - PullRequest
2 голосов
/ 03 февраля 2012
void SomeClass::mySlot(MyClass *var){
    ...
}

void SomeClass::SomeFunction(){
    MyClass *myVar;
    QPushButton *button = new QPushButton(this);
    connect(button, SIGNAL(clicked()), this, SLOT(mySlot(myVar)));
}

Я хочу, чтобы mySlot получал myVar при нажатии кнопки.Возможно ли сделать что-то подобное?Я не хочу хранить указатель myVar в SomeClass.

обновление (мое решение):

void SomeClass::mySlot(){
    QPushButton *button = static_cast<QPushButton*>(sender());  
    MyClass *myVar = qobject_cast<MyClass*>(qvariant_cast<QObject *>(button->property("myVar")));
    ...
}

void SomeClass::SomeFunction(){
    MyClass *myVar;
    QPushButton *button = new QPushButton(this);
    button->setProperty("myVar", QVariant::fromValue((QObject*)myVar));
    connect(button, SIGNAL(clicked()), this, SLOT(mySlot()));
}

Ответы [ 2 ]

3 голосов
/ 03 февраля 2012

Нет, это невозможно. Вы можете использовать слот, который отбрасывает некоторые параметры, но не слот, который имеет больше параметров, чем сигнал. Кроме того, вы не можете передать переменную при подключении слота.

2 голосов
/ 03 февраля 2012

Вы можете сделать это с QSignalMapper (см. Пример там для использования) с некоторыми ограничениями, но вы должны быть очень осторожны с временем жизни объекта.

QSignalMapper *signalMapper = new QSignalMapper(this);
MyClass *myVar = new ...;

QPushButton *button = new QPushButton(this);
connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button, myVar);

connect(signalMapper, SIGNAL(mapped(MyClass*)),
         this, SIGNAL(MySlot(MyClass*)));

(Обратите внимание, что MyClass должно быть получено из QObject или QWidget.)

Это будет работать до тех пор, пока объект, на который указывает myVar, остается действительным (то есть не удаляется), но если вы не сохраните указатель на этот объект где-либо, вы не сможете его легко удалить. - чтобы у вас могла быть утечка памяти. (Если вы держитесь за отображение сигнала и указатель кнопки, вы можете восстановить этот объект с помощью mapping члена QSignalMapper.)

С другой стороны, следующий не будет работать :

QSignalMapper *signalMapper = new QSignalMapper(this);
MyClass myVar;
...
signalMapper->setMapping(button, &myVar); // WRONG
...

Это не может работать, потому что в этом случае объект, на который ссылается myVar, уничтожается, когда заканчивается someFunction, поэтому слот получит недопустимый указатель, что приведет к неопределенному поведению (то есть может произойти что угодно - ошибка, сбой, вещи, кажущиеся работающими, иногда не другие, ...).

...