Russian Qt Forum
Ноябрь 26, 2024, 05:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: Сигнал, и его обработка во время выполнения другой функции, равно сегфолт  (Прочитано 22636 раз)
SABROG
Гость
« Ответ #15 : Декабрь 15, 2008, 12:20 »

QFileSystemModel не используется случайно ?

Код
C++ (Qt)
void QFileSystemModel::setIconProvider(QFileIconProvider *provider)
{
   Q_D(QFileSystemModel);
   d->fileInfoGatherer.setIconProvider(provider);
   qApp->processEvents();
   d->root.updateIcon(provider, QString());
}
« Последнее редактирование: Декабрь 15, 2008, 12:42 от SABROG » Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #16 : Декабрь 15, 2008, 13:54 »

Ну и я обычно дизаблю всё главное окно на время "атомарных" действий.

А подробнее, что имеется в виду под дизаблингом главного окна?


Ну или диалог из инициировавший.

Диалог, их (атомарные действия) инициировавший? А как его дизаблите? Так же как и главное окно?
Записан

Собираю информацию по крупицам
http://webhamster.ru
SABROG
Гость
« Ответ #17 : Декабрь 15, 2008, 14:19 »

Вероятно так:

Код
C++ (Qt)
treeView->setDisabled(true);
...
treeView->setEnabled(true);
 
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #18 : Декабрь 15, 2008, 14:24 »

В доке не уточнен момент.

При вызове setDisabled(true) конкретного виджета, будут ли заблокированы input events для всех вижджетов, входящих в блокируемый виджет?
Записан

Собираю информацию по крупицам
http://webhamster.ru
SABROG
Гость
« Ответ #19 : Декабрь 15, 2008, 15:02 »

В доке не уточнен момент.

При вызове setDisabled(true) конкретного виджета, будут ли заблокированы input events для всех вижджетов, входящих в блокируемый виджет?

Да, все дочерние виджеты отрубятся тоже, в миг посереют.
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #20 : Декабрь 15, 2008, 21:37 »

У меня что-то с глазами, или действительно в этой ветке удалена мессага кого-то из админов про blockSignals? Хотелось бы еще раз увидеть этот код, не успел я его толком посмотреть.
Записан

Собираю информацию по крупицам
http://webhamster.ru
spirit
Гость
« Ответ #21 : Декабрь 15, 2008, 21:52 »

Код
C++ (Qt)
...
bool isBlocked = trmodel->blockSignals(true);
trmodel->removeRow(index.row(), index.parent());
trmodel->blockSignals(isBlocked);
...
 
« Последнее редактирование: Декабрь 15, 2008, 21:54 от spirit » Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #22 : Декабрь 15, 2008, 23:05 »

В общем, нашел я в чем проблема. Проблема возникает в двух случаях

1. Из-за незаблокированного интерфейса (поборол). То есть если в процессе удаления успеть кнуть на другую ветку, получим гарантированный сегфолт. Проблему решил командами

Код
C++ (Qt)
mainwindow->setDisabled(true);
mainwindow->blockSignals(true);
...
mainwindow->setEnabled(true);
mainwindow->blockSignals(false);

не знаю, может и избыточно, можно былоб обойтись только setDisabled() setEnabled(), но в доке по этим методам про блокировку сигналов ничего не сказано, только про "события".


2. Из-за переустановки сигналов при смене модели для QListView (побороть не смог). Когда меняется ветка в QTreeView, модель в QListView заменяется через метод setModel(). Сразу после этой команды приходится связывать сигналы

Код
C++ (Qt)
// Загрузка модели в представление
recordview->setModel(mod);
 
// Сигнал для обработки движения стрелок в списке конечных записей
connect(recordview->selectionModel(), SIGNAL(currentRowChanged (const QModelIndex&, const QModelIndex&)),
        this, SLOT(select(const QModelIndex&)));
// Сигналы для обновления панели инструментов
connect(recordview->selectionModel(), SIGNAL(currentChanged (const QModelIndex&, const QModelIndex&)),
        this, SLOT(tools_update(void)));
connect(recordview->selectionModel(), SIGNAL(selectionChanged (const QItemSelection&, const QItemSelection&)),
        this, SLOT(tools_update(void)));

Это нужно делать, так как при смене модели связка сигналов для selection model удаляется, о чем написано в доке и проверено на практике

Цитировать
Note that, if you call setModel() after this function, the given selectionModel will be replaced by one created by the view.

То есть, если сигналы определить один раз в инициализации всего виджета, то при смене модели они перестанут работать. Поэтому их и приходится заново прописывать после смены модели.

Дело осложняется тем, что в глубине процедуры удаления веток происходит вызов смены модели для QListView (когда перебираются удаляемые подветки). И если мы перед процедурой удаления заблокировали все connection, то внутри процедуры удаления они заново создаются. Потом вызывается слот (при удалении строк в QListView) в получается сегфолт.

Я думал, что mainwindow->setDisabled(true) заблокирует глобально все. Т.е. просто не будут ходить сигналы. И потому вновьсозданные сигналы не будут работать. Но оказываются, они работают...


Вопрос: как с минимальными потерями выйти из этой ситуации? Так, чтобы и идеологически правильно, и код тоннами не перелопачивать?


ЗЫЖ: В общем, я с самого начала проектировал прогу не зная таких особенностей. Теперь не преццтавляю что делать - переделывать всю логику взаимодействия виджетов - это прощще весь проект переписать. У меня действительно сильно завязаны функции представления данных на экране и функции работы с данными, одно вызывает другое, и я слабо понимаю, как по-другому можно делать пользовательский интерфейс (а я раньше их и не проектировал).
Записан

Собираю информацию по крупицам
http://webhamster.ru
ритт
Гость
« Ответ #23 : Декабрь 15, 2008, 23:47 »

Цитировать
Дело осложняется тем, что в глубине процедуры удаления веток происходит вызов смены модели для QListView (когда перебираются удаляемые подветки). И если мы перед процедурой удаления заблокировали все connection, то внутри процедуры удаления они заново создаются. Потом вызывается слот (при удалении строк в QListView) в получается сегфолт.
где? имя файла и номер строчки можно?
или это личная прихоть?
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #24 : Декабрь 16, 2008, 00:30 »

Цитировать
Дело осложняется тем, что в глубине процедуры удаления веток происходит вызов смены модели для QListView (когда перебираются удаляемые подветки). И если мы перед процедурой удаления заблокировали все connection, то внутри процедуры удаления они заново создаются. Потом вызывается слот (при удалении строк в QListView) в получается сегфолт.
где? имя файла и номер строчки можно?
или это личная прихоть?

Ну да, это личная прихоть, так организована программа. Когда в дереве удаляется ветка, пробегаются все подветки. Для каждой ветки-подветки вызывается процедура удаления данных из строк, представленных в QListView. При смене подветки, в QListView вставляется новая модель. При этом приходится создавать сигналы, ну и имеем то что имеем.

Я конечно могу сделать глобальный флаг, типа "идет атомарная операция", и в эти моменты в тех местах где "динамически" создаются connection, их не создавать (всеравно они создастья сами потом при пользовании интерфейса. Хотя, чтоб они создались, возможно придется что-то один раз передергивать). Это не самый лучший метод, хотя работать будет.


Поэтому, я хочу узнать более правильный метод.
Записан

Собираю информацию по крупицам
http://webhamster.ru
ритт
Гость
« Ответ #25 : Декабрь 16, 2008, 00:39 »

Поэтому, я хочу узнать более правильный метод.

не подменяй модель, пока вьюха обрабатывает её айтемы...
Записан
xintrea
Супер активный житель
*****
Offline Offline

Сообщений: 754



Просмотр профиля WWW
« Ответ #26 : Декабрь 16, 2008, 01:00 »

не подменяй модель, пока вьюха обрабатывает её айтемы...

О, это мысль. А каким методом узнавать что вьюха обрабатывает айтемы?
Записан

Собираю информацию по крупицам
http://webhamster.ru
ритт
Гость
« Ответ #27 : Декабрь 16, 2008, 01:39 »

перефразирую: "не подменяй модель"

представь, что модель - это указатель на буффер, а вьюха - цикл, в котором используется данный указатель (для перебота элементов, например). что случится, если во время модификации буффера ты вдруг подменишь указатель на какой-нибудь другой буффер (а если ещё и размер/тип данных отличается)?

работай с моделью как с источником данных, а вьюха пусть выполняет своё предназначение - визуализацию данных, навигацию и т.д.
Записан
BRE
Гость
« Ответ #28 : Декабрь 16, 2008, 09:02 »

Не меняй модель. Сделай в ней слот, который будет ее перестраивать в зависимости от выбранной ветки. Свяжи сигнал изменения ветки в knowtree с этим сигналом.
При смене ветки, модель для recordview настроится для отображения выбранной ветки, и сделает emit layoutChanged(), recordview ее перечитает и выведет на экран.
Записан
Tonal
Гость
« Ответ #29 : Декабрь 16, 2008, 10:00 »

В любой нормальной оконной системе отключение (запрещение? дизабление?) не отменяет все события.
Оно нужно чтобы информировать пользователя о том что сейчас сюда тыкать не нужно. Улыбающийся
Отключённое окно можно сворачивать/разворачивать, оно правильно отрисовывается, работают таймеры и т.д.

По поводу второго глюка: согласен с BRE.
Да и вообще по хорошему, нужно стараться как можно больше развязать GUI и свои данные.
Т.е. всякие виджеты и модели использовать только для отображения и получения событий от пользователя.
А при получении событий сразу же формировать необходимый набор параметров и звать уже свои функции из своих классов данных.
Так при очередной смене версий Qt или самого фреймворка понадобиться переписать только GUI-часть, а логика данных останется. Улыбающийся

Да, есть ещё "быстрое" решение твоей проблемы - без переработки дизайна. Улыбающийся
Вынеси всю настройку ListView-а в отдельную функцию и вызови её потом - после окончания всей обработки.
Удобно делать это с помощью QTimer::singleShot с небольшим таймоутом.
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.135 секунд. Запросов: 23.