Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/11: Рейтинг темы: голосов - 11, средняя оценка - 5.00
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,135
Записей в блоге: 2
1

Завершить работу слота (закрыть диалог) потока, если извне для него была вызвана exit()

15.08.2014, 18:37. Показов 1975. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Привет!
С Qt работал мало и очень давно, поэтому задаю такие вопросы.
Смотрите - в самом приложении есть слоты, в которых запускаются потоки (в идеале хочу сделать так - в одном слоте поток запускается, в другом убивается).
Первая проблема, с которой я столкнулся - это гуй (оказалось, что я не могу из созданного потока рисовать гуй), поэтому придумал такой обходной путь:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//в классе потока
public slots:
    void slotWithGui(const CrewExctracter*);
 
signals:
    void needGui(const CrewExctracter*);
 
 
//в main thread (который с GUI)
connect (exctracter, SIGNAL(needGui(const CrewExctracter*)), this, SLOT(slotThreadNeedGui(const CrewExctracter*)));
connect (this, SIGNAL(letGui(const CrewExctracter*)), exctracter, SLOT(slotWithGui(const CrewExctracter*)));
// где exctracter - указатель на CrewExctracter, который в свою очередь наследуется от QThread
 
//ну и как не сложно догадаться slotThreadNeedGui
void Registrator::slotThreadNeedGui(const CrewExctracter *ce)
{
    emit letGui(ce);
}
метод потока run выглядит примерно так
C++ (Qt)
1
2
3
4
5
void run()
{
    emit needGui(this);
    exec();
}
т.е. я сразу перехожу в слот с гуем, где и выполняется вся работа потока.
Так вот, когда в main thread дергается слот, где я хочу завершить работу созданного потока у меня там такой код
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
    if (threads.contains(dev)) { // threads - это QMap<QSting, QThread*>, dev - та самая строка, к которой привязан QThread*
        QThread *thread = threads[dev];
        if (thread->isRunning()) {
            thread->exit(0);
            thread->wait();
        }
 
        delete thread;
        threads.remove(dev);
    }
проблема в том, что тут все отрабатывает нормально, НО если в это время в созданном потоке открыт какой-нибудь QMessageBox, то он так и остается открытым, более того после его закрытия работа слота потока продолжает работать и приложение (как назло не всегда) крэшится.

Скажите что я делаю не так и как мне сделать все грамотно?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.08.2014, 18:37
Ответы с готовыми решениями:

Форма не прорисовывается до конца, если была вызвана из другого потока
У меня небольшая проблема, я подозреваю, что проблема с межпотоковой безопасностью( а может оно и...

Завершить работу потока при закрытии формы
procedure TForm1.BStartClick(Sender: TObject); begin ProgressBar1.Max := SLRepairFiles.Count; ...

Добавить ф-цию в прототип, которая модифицирует объект, для которого она была вызвана
Здравствуйте! Название темы длинное получилось, надеюсь на примере будет понятно. Написал ф-цию,...

Проверить дату создания файла и если не совпадает - завершить работу
Пишу код. Хочу что бы скрипт проверил дату создания файла и если не совпадает завершил работу: ...

9
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
15.08.2014, 20:45 2
Все просто. Все что связано с GUI в потоке делать нельзя. Вообще вызвать все QtGui/QtWidgets классы в потоке нельзя.

В дочерних потоках обработка. В основном интерфейс.
0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,135
Записей в блоге: 2
15.08.2014, 20:59  [ТС] 3
RazrFalcon, это я знаю. Но мне нужно очень часто показывать всякие MessageBox'ы, диалоги и пр.
Элементарно - показать диалог "файл не существует. Создать? да/нет". Как тогда можно это организовать?
0
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
15.08.2014, 21:27 4
Посылать из потока сигнал с QString содержащий текст сообщения, а в слоте в главном потоке отображать уже само сообщение.
0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,135
Записей в блоге: 2
15.08.2014, 22:36  [ТС] 5
Цитата Сообщение от RazrFalcon Посмотреть сообщение
Посылать из потока сигнал с QString содержащий текст сообщения, а в слоте в главном потоке отображать уже само сообщение.
Я сначала так и делал, но встал вопрос - как дождаться ответа от главного потока (не костыльно). Сделал опять же через сигналы/слоты, но потом их столько наплодилось, что самому стало сложно читать. Поэтому все удалил и переделал.
делал так
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// в потоке
emit showMessageBox("text");
// больше в этой ф-ции ничего не делал
 
// в main thread
void slotShowMessageBox(QString &msg)
{
    QMessageBox::button answer;
    // показываем диалог 
    emit answer(answer);
}
 
 
// в потоке
void slotAnswer(QMessageBox::button button)
{
    // тут понятно какую кнопку нажал пользователь, можно продолжать работать
}
не сложно представить, что если мне надо хотя бы десяток мессаджбоксов и столько же диалогов, где нужен ввод строки от пользователя, то в итоге у меня получилось "мама дорогая".
Поэтому плюнул и переписал так, как есть.

Добавлено через 19 минут
В очередной раз попробовал погуглить по поводу показа гуя в главном потоке через сигналы/слоты. Вроде говорят Qt::BlockingQueuedConnection решает мою проблему (100500 сигналов и слотов). Завтра попробую, отпишусь.
0
1403 / 1260 / 262
Регистрация: 10.11.2013
Сообщений: 3,763
15.08.2014, 22:54 6
Так если нужно постоянно тормозить поток - может он и не нужен?

Не понял зачем вам 100500 сигналов слотов? В сигнале передаем какой нам нужен тип диалога, ну а ответ такой же как сейчас. Итого два connect'a и все.
1
1 / 1 / 2
Регистрация: 15.08.2014
Сообщений: 5
16.08.2014, 00:01 7
Вот зауважаю и Kastaneda, если верно, что
Так если нужно постоянно тормозить поток - может он и не нужен?
и притом Kastaneda перейдёт к этому подходу. Сам я только стал смотреть на свои Java2ME приложениеца, малоопытен, а тоже стараюсь уже немножко по собственному опыту минимизировать охваченность сырых методов вложенными или лишними
Java
1
synchronized
0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,135
Записей в блоге: 2
16.08.2014, 09:44  [ТС] 8
Цитата Сообщение от RazrFalcon Посмотреть сообщение
Так если нужно постоянно тормозить поток - может он и не нужен?
Нет, нужен. В общих чертах суть программы - программа всегда висит в фоне, реагирует на любой новый вставленный накопитель (флешка и т.д.), для каждого нового накопителя запускается свой поток, который (если опустить подробности) копирует файлы с накопителя на диск. Может быть ситуация, когда вставят сразу 10 флешек, поэтому потоки нужны.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.08.2014, 12:19 9
Вспомогательный поток с эвент лупом :
1. Когда надо шлет сообщение основному что нужно вызвать диалог, после чего поток упирается в эвент луп и ждет сигнала что бы продолжить работу.
2. После того как диалог будет закрыт основной поток высылается сигнал вспомогательному потоку что он может продолжить свою работу.
0
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,135
Записей в блоге: 2
18.08.2014, 21:21  [ТС] 10
Вобщем я все переписал. Во первых потоки организовал вот так, во вторых гуй показываю в слоте в main thread через сигналы, а коннекчусь через Qt::BlockingQueuedConnection, который действительно работает
1
18.08.2014, 21:21
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.08.2014, 21:21
Помогаю со студенческими работами здесь

Выполнение слота основного потока через сигнал второстепенного потока
Доброго времени суток! Вопрос следующий. В основном потоке создается кнопка и Qlabel class...

Узнать кем была вызвана активность
Ребята подскажите можно ли узнать с помощью какой активности была запущена новая &quot;текущая&quot;...

Определение, откуда была вызвана функция
Как это сделать? Например есть L.lua function start() end и еще два файла a.lua и b.lua...

Как получить строку из которой была вызвана функция?
Предварительный просмотр Как получить строку и файл, из которой была вызвана функция? Например:...

Узнать адрес ячейки из которой была вызвана функция
Добрый день форумчане. я не спец в VBA. перед мной стала задача: узнать адрес ячейки из которой...

Нужен компьютер: 4 ядра,DD3 память,два слота для видеокарты и 4 слота для ОЗУ
Я хочу собрать комп. Чтобы Intel 4 ядра 3.0Ггц честота шины 1066.Мать подерживала DDR2 и DDR3,2...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru