LINUX.ORG.RU

Можно ли передать сигнал в метод и там его вызвать?

 ,


0

1

Есть 2 метода, которые отличаются только сигналом, который они эммитят. Очень хочется обобщить их, но в этом случае необходимо в обобщенный метод передать как-то сигнал (сигнал с параметром). Сейчас сделал передачей в метод лямбды, в которой делаю эммит, но сей вариант мне не очень нравится. Как можно покрасивше решить задачу?

а параметр передать в метод? в зависимости от параметра выдавать нужный сигнал? А вообще я стараюсь разбить на функции такие вещи

void C::f() {
   f1();
   if(...) {
       emit sig1();
   }
   else {
       emit sig2()
   }
   f2();
}

вместо

void C::f() {
   ...
   f1(true);
   ...
}

void C::f1(bool p) {
   ...
   if(p) {
       emit sig1();
   }
   else {
       emit sig2()
   }
   ...
}

Можно еще сам сигнал с параметром сделать

energyclab
()

Вот копипаста кода:

	void checkStatisticTypes(CTransaction* transaction, std::function<void(const QStringList&)> emitedSignal)
	{
		if (!m_waitingSaveStatisticTypes.isEmpty())
		{
			const QStringList names = eraseStatisticTypesForTransaction(transaction);

			if (!names.isEmpty())
				emitedSignal(names);
		}
	}

	void checkForSaveStatisticTypes(CTransaction* transaction)
	{
		checkStatisticTypes(transaction, [this](const QStringList & names) {emit statisticTypesAdded(names);});
	}

	void checkForIgnoreStatisticTypes(CTransaction* transaction)
	{
		checkStatisticTypes(transaction, [this](const QStringList & names) {emit statisticTypesNotAdded(names);});
	}
panter_dsd ★★★★
() автор топика
Ответ на: комментарий от energyclab

Ненавижу передачу флагов в параметрах. Плюс, придется еще делать слот, который анализирует сей флаг, что не есть красиво.

panter_dsd ★★★★
() автор топика
Ответ на: комментарий от panter_dsd

а может тогда напрямую сконектить сигналы, по которым вызываются checkForSaveStatisticTypes и checkForIgnoreStatisticTypes с их аналогами лямбды?

energyclab
()
Ответ на: комментарий от panter_dsd

1. Слово emit - синтаксический сахар, достаточно вызвать метод.

2. Передавай сразу метод класса

3. Ты же всегда заранее знаешь какой сигнал тебе будет нужен -> можно шаблоном

Stil ★★★★★
()
Ответ на: комментарий от Stil
	void checkStatisticTypes(CTransaction* transaction, std::function<void(const QStringList&)> emitedSignal)
	{
		if (!m_waitingSaveStatisticTypes.isEmpty())
		{
			const QStringList names = eraseStatisticTypesForTransaction(transaction);

			if (!names.isEmpty())
				emitedSignal(names);
		}
	}

	void checkForSaveStatisticTypes(CTransaction* transaction)
	{
		checkStatisticTypes(transaction, TransactionObserver::statisticTypesAdded);
	}

	void checkForIgnoreStatisticTypes(CTransaction* transaction)
	{
		checkStatisticTypes(transaction, &TransactionObserver::statisticTypesNotAdded);
	}

Выдает:

platform/src/plugins/statistic/cstatisticmanager.cpp: In member function 'void TransactionObserver::checkForSaveStatisticTypes(CTransaction*)':
platform/src/plugins/statistic/cstatisticmanager.cpp:183:76: error: no matching function for call to 'TransactionObserver::checkStatisticTypes(CTransaction*&, <unresolved overloaded function type>)'
   checkStatisticTypes(transaction, TransactionObserver::statisticTypesAdded);
                                                                            ^
platform/src/plugins/statistic/cstatisticmanager.cpp:183:76: note: candidate is:
platform/src/plugins/statistic/cstatisticmanager.cpp:170:7: note: void TransactionObserver::checkStatisticTypes(CTransaction*, std::function<void(const QStringList&)>)
  void checkStatisticTypes(CTransaction* transaction, std::function<void(const QStringList&)> emitedSignal)
       ^
platform/src/plugins/statistic/cstatisticmanager.cpp:170:7: note:   no known conversion for argument 2 from '<unresolved overloaded function type>' to 'std::function<void(const QStringList&)>'
platform/src/plugins/statistic/cstatisticmanager.cpp: In member function 'void TransactionObserver::checkForIgnoreStatisticTypes(CTransaction*)':
platform/src/plugins/statistic/cstatisticmanager.cpp:188:80: error: no matching function for call to 'TransactionObserver::checkStatisticTypes(CTransaction*&, void (TransactionObserver::*)(const QStringList&))'
   checkStatisticTypes(transaction, &TransactionObserver::statisticTypesNotAdded);
                                                                                ^
platform/src/plugins/statistic/cstatisticmanager.cpp:188:80: note: candidate is:
platform/src/plugins/statistic/cstatisticmanager.cpp:170:7: note: void TransactionObserver::checkStatisticTypes(CTransaction*, std::function<void(const QStringList&)>)
  void checkStatisticTypes(CTransaction* transaction, std::function<void(const QStringList&)> emitedSignal)
       ^
platform/src/plugins/statistic/cstatisticmanager.cpp:170:7: note:   no known conversion for argument 2 from 'void (TransactionObserver::*)(const QStringList&)' to 'std::function<void(const QStringList&)>'
panter_dsd ★★★★
() автор топика

В Qt5 сигнал — обычная функция член. Передаёшь функцию член как аргумент и дёргаешь её. Если типы у функций разные — пишешь шаблон.

KblCb ★★★★★
()
Ответ на: комментарий от panter_dsd

ну можно конектиться напрямую к лямбдамЯ так понимаю, что у тебя есть два сигнала с параметром CTransaction*, Вот их приконектить к лямбдам как то так:

connect(sender, &Sender::sig1, [this](CTransaction* transaction){emit statisticTypesAdded(this -> names);});

connect(sender, &Sender::sig2, [this](CTransaction* transaction){emit statisticTypesNotAdded(this -> names);});

Если я что то напутал с кодом, просьба поправить

energyclab
()
Ответ на: комментарий от Stil

1. Слово emit - синтаксический сахар, достаточно вызвать метод.

Нет, в зависимости от типа соединения оно действует по-разному. Яркий пример: Queued vs Direct connections

Но насчёт синтаксического сахара — ты прав. Moc разворачивает его в менее понятную конструкцию. Короче вот, про emit/Q_EMIT: http://qt-project.org/doc/qt-4.8/qobject.html#Q_EMIT

KennyMinigun ★★★★★
()
Последнее исправление: KennyMinigun (всего исправлений: 1)

Сделал через бинд, это симпотишнее лямбды.


	void checkStatisticTypes(CTransaction* transaction, std::function<void(const QStringList&)> emitedSignal)
	{
		if (!m_waitingSaveStatisticTypes.isEmpty())
		{
			const QStringList names = eraseStatisticTypesForTransaction(transaction);

			if (!names.isEmpty())
				emitedSignal(names);
		}
	}

	void checkForSaveStatisticTypes(CTransaction* transaction)
	{
		checkStatisticTypes(transaction, std::bind (&TransactionObserver::statisticTypesAdded, this, _1));
	}

	void checkForIgnoreStatisticTypes(CTransaction* transaction)
	{
		checkStatisticTypes(transaction, std::bind (&TransactionObserver::statisticTypesNotAdded, this, _1));
	}
panter_dsd ★★★★
() автор топика
Ответ на: комментарий от nanoolinux

Я уже довольно давно пишу большую часть кода на хаскеле и банально забыл как термин метод так и то почему я не хотел его тут использовать. Замечание на тему «дёрнуть» считаю демагогией.

KblCb ★★★★★
()
Ответ на: комментарий от panter_dsd

И это уродство ты предпочел булевому флажку? Мда...

ncuxer
()

Не знаю как в пятом Qt, а в четвертом сигнал передается как const char* и может быть вызван через QMetaObject::invokeMethod

Torvus
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.