100 строк где-то в первых строках высылается сигнал emit signal(), то когда в рантайме его получит обработчик этого сигнала, относительно выполнения самого emit? То бишь сигнал выслан в первых строках функции или метода по ходу выполнения, то не будет ли он обработан только тогда, когда в этой функции будут выполнены все строки кода?
зависит от способа соединения сигнала со слотом в случае диеркт вызовется немедленно, но в треде, который сигнал испустил. если это не устраивает, но хочется быстро, то есть волшебный QApplication::processEvents, который немедленно попросит евентлуп обработать очередь сообщений
А если слот-обработчик в другом потоке вызывается?
https://doc.qt.io/qt-6/threads-qobject.html
что значит слот-обработчик в другом потоке вызывается? если ты укажешь директ, то слот вызовется в потоке сигнала.
https://doc.qt.io/qt-6/qt.html#ConnectionType-enum
зависит от типа соединения. но мне кажется плохая практика завязываться на то когда обработается сигнал. ты эмитишь сигнал и не знаешь когда он обработается, может и не обработается вообще
Да я вот не знаю, как это реализовать не костыльно: мне нужно отправить из одного объекта сигнал в другой объект, и тут же получить результат выполнения обработки этого сигнала.
тут кажется только через сигнал от другого объекта. сигнал\слоты не для последовательного выполнения кода
Кажется легко такое можно реализовать в Qt6 с помощью QtConcurrent и then. В then передать контекст объекта, и функция. Функция будет выполняться в треде где находится сам объект. Несколько then и все будет последовательно. Но выглядеть будет костыльно
эти объекты в разных потоках?
Слот будет вызван НЕПОСРЕДСТВЕННО в этой строчке, где emit . Но есть нюансы. Связывание сигналов и слотов имеет параметр - тип связи, есть связи с отложенным исполнением и из другого потока. Если связи такого рода, то момент вызова не определён.
ну я то задним умом понимаю, что вариантов то по сути немного, можно или в очередь вызов поставить, либо непосредственно выполнить вызов слота в месте эмита сигнала
Ну при этом ещё и ошибка будет, что ты direct связал сигнал и слот разных потоков
Результат также при Direct connection возвращается непосредственно. Но только у слотов нет выходных данных, на сколько я помню
откуда такая уверенность? 😜 ошибки не будет связать имеешь право, если точно знаешь, что делаешь. То что авто делает именно так означает только то, что так наиболее безопасно, не более. class ChildThread { .... } class MainThread { .... childThread=new ChildThread(..); connect(this,&MainThread::signal,childThread,&ChildThread::slot, Qt::DirectConnection); } тут emit siagnl(..) из mainThread по сути эквивалентен прямому вызову childThread->slot() и в чем тут ошибка?
В рантайме ошибка будет. Ну, QAcssert и далее в зависимости от настроек
вообще да, слот всегда void возвращает, поэтому видимо только моим способом
Вообще, это называется просто "вызов функции"
Ну вообще все в программировании построено на вызовах функций) но я не могу взять и вызвать функцию из другого потока напрямую, причём такую функцию, которая внутри своего выполнения выполняет connect () для reply, который ожидает ввод/вывод
Можно подробней что вам нужно сделать? Вот есть GUI поток основной и поток игровой логики. Вам нужно нажать условную кнопку и выполнить действие которое включает получение результата метода из объекта который в потоке игровой логики? и чтобы GUI Не завис? Я ничего не упустил?
почему вдруг из другого потока-то ?
В общем ты там разберись, кто на ком стоял
сообщением выше я раскрываю весь вопрос)
ошибка в рантайм будет только в том случае, если определенные операции ты попробуешь сотворить в этом слоте над объектами, которые были созданные в child потоке есть то, чего делать нельзя. Например из другого потока ты не можешь убить объект, созданный в другом. но, ты запросто можешь делать иные вещи. Объви членом класса ChildThread переменную типа, ну QString и поменяй в этом слоте ее значение... и покажи как и что упадет emit signal TMainWnd(0x6336bff440, name="TMainWnd") slot TPrinterWorker(0x1d6524bd0d0) private boolean variable value before: false slot TPrinterWorker(0x1d6524bd0d0) private boolean variable value after: true
что про это? никакой ошибки, все штатно и работает дальше... это я в дебуг сообщения выкинул, коннект директовый
Обсуждают сегодня