Название: [решено] QLineEdit returnPressed() Отправлено: serg_hd от Июня 25, 2011, 17:53 Проблема, на первый взгляд, пустяковая. Есть класс (содержит gui), наследник QWidget'a, в нём кнопка и текстовое поле. При нажатии на кнопку шлётся сигнал по которому этот класс зачищается родительским. Захотел то же самое сделать для текстового поля:
Код
При испускании сигнала accept() сам класс зачищается. Проблема в том, что если нажимать кнопку - всё ок, форма закрывается и чистится (у родителя этот класс в QScopedPointer'е). Но если нажать Enter на поле ввода, то в 70% случаев - segfault, но иногда тоже всё норм. Казалось бы, какие могут быть проблемы, когда оба сигнала - и кнопка и поле ввода соединены с одним и тем же сигналом класса. Пробовал также перед зачисткой ставить фокус на родительском виджете, не помогает (обычно из-за фокуса бывают такие проблемы, если его не сбрасывать перед зачисткой). Совершенно непонятно в чём причина... Название: Re: QLineEdit returnPressed() Отправлено: Disaron от Июня 25, 2011, 19:00 Чисто предположение: может returnPressed() соединен по дефолту с чем-то еще, и это что-то следует отсоединить предварительно?
А то мало ли что там connectSlotsByName() и иже с ним натворит. Я бы попробовал проэкспериментировать так : Код
Название: Re: QLineEdit returnPressed() Отправлено: serg_hd от Июня 25, 2011, 20:23 Чисто предположение: может returnPressed() соединен по дефолту с чем-то еще, и это что-то следует отсоединить предварительно? пробовал, изначально именно так и делалА то мало ли что там connectSlotsByName() и иже с ним натворит. Я бы попробовал проэкспериментировать так : Код
Название: Re: QLineEdit returnPressed() Отправлено: LisandreL от Июня 25, 2011, 20:31 попробуйте для этого сигнала тип коннекта Qt::QueuedConnection поставить. Может там в функции, вызывающей сигнал ещё после него обращения к объектам идёт и из-за тог, что они уже не существуют всё накреняется.
Название: [решено] QLineEdit returnPressed() Отправлено: serg_hd от Июня 25, 2011, 22:04 попробуйте для этого сигнала тип коннекта Qt::QueuedConnection поставить. Может там в функции, вызывающей сигнал ещё после него обращения к объектам идёт и из-за тог, что они уже не существуют всё накреняется. Проканало, благодарствую. Но всё равно не понимаю почему так работает. Если бы знал, что QLineEdit завязан на момент испускания сигнала с кем-то ещё, то и сам изначально этот тип сигнала бы указал. Но ведь ни он, ни qpushbutton, к которому этот же слот вешаю (без queuedconnection и работает) ни с кем больше не завязаны. Кстати, valgrind ругался: Код: Invalid read of size 4 Название: Re: [решено] QLineEdit returnPressed() Отправлено: LisandreL от Июня 26, 2011, 00:43 Проканало, благодарствую. Но всё равно не понимаю почему так работает. Если бы знал, что QLineEdit завязан на момент испускания сигнала с кем-то ещё, то и сам изначально этот тип сигнала бы указал. Если посмотреть исходники, то внутри QLineEdit используется QLineControl.Код
emit accepted(); - реэмитится в QLineEdit::returnPressed(), а emit editingFinished() - в QLineEdit::editingFinished(). Таким образом при прямом соединении весь последующий код выполняется уже по разрушенным обектам: Цитировать if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) { что черевато.if (hasAcceptableInput() || fixup()) { emit accepted(); emit editingFinished(); } if (inlineCompletionAccepted) event->accept(); else event->ignore(); return; } Название: Re: [решено] QLineEdit returnPressed() Отправлено: serg_hd от Июня 26, 2011, 03:41 до просмотра исходников реализации QLineEdit'а доходить не решился, но со стороны его разработчиков не упомянуть такого в документации (рекомендацию использовать queuedconnection при сигнале returnPressed()), по-моему, не есть хорошо.
Название: Re: [решено] QLineEdit returnPressed() Отправлено: BRE от Июня 26, 2011, 04:09 до просмотра исходников реализации QLineEdit'а доходить не решился, но со стороны его разработчиков не упомянуть такого в документации (рекомендацию использовать queuedconnection при сигнале returnPressed()), по-моему, не есть хорошо. Просто не стоит в слотах разрушать объект инициирующий выполнение этого слота! Для этого лучше воспользоваться специальным методом deleteLater(). |