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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [решено] QLineEdit returnPressed()  (Прочитано 6721 раз)
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« : Июнь 25, 2011, 17:53 »

Проблема, на первый взгляд, пустяковая. Есть класс (содержит gui), наследник QWidget'a, в нём кнопка и текстовое поле. При нажатии на кнопку шлётся сигнал по которому этот класс зачищается родительским. Захотел то же самое сделать для текстового поля:
Код
C++ (Qt)
QObject::connect(this->ui->btnOk, SIGNAL(pressed()), SIGNAL(accept()));
QObject::connect(this->ui->leCount, SIGNAL(returnPressed()), SIGNAL(accept()));
 

При испускании сигнала accept() сам класс зачищается. Проблема в том, что если нажимать кнопку - всё ок, форма закрывается и чистится (у родителя этот класс в QScopedPointer'е). Но если нажать Enter на поле ввода, то в 70% случаев - segfault, но иногда тоже всё норм. Казалось бы, какие могут быть проблемы, когда оба сигнала - и кнопка и поле ввода соединены с одним и тем же сигналом класса. Пробовал также перед зачисткой ставить фокус на родительском виджете, не помогает (обычно из-за фокуса бывают такие проблемы, если его не сбрасывать перед зачисткой). Совершенно непонятно в чём причина...
« Последнее редактирование: Июнь 25, 2011, 22:04 от serg_hd » Записан

kubuntu/Win7/x64/NetBeans
Disaron
Гость
« Ответ #1 : Июнь 25, 2011, 19:00 »

Чисто предположение: может returnPressed() соединен по дефолту с чем-то еще, и это что-то следует отсоединить предварительно?
А то мало ли что там connectSlotsByName() и иже с ним натворит.
Я бы попробовал проэкспериментировать так :
Код
C++ (Qt)
QObject::connect(this->ui->leCount, SIGNAL(returnPressed()), this->ui->btnOk, SIGNAL(pressed()));
« Последнее редактирование: Июнь 25, 2011, 19:13 от Disaron » Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #2 : Июнь 25, 2011, 20:23 »

Чисто предположение: может returnPressed() соединен по дефолту с чем-то еще, и это что-то следует отсоединить предварительно?
А то мало ли что там connectSlotsByName() и иже с ним натворит.
Я бы попробовал проэкспериментировать так :
Код
C++ (Qt)
QObject::connect(this->ui->leCount, SIGNAL(returnPressed()), this->ui->btnOk, SIGNAL(pressed()));
пробовал, изначально именно так и делал
Записан

kubuntu/Win7/x64/NetBeans
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #3 : Июнь 25, 2011, 20:31 »

попробуйте для этого сигнала тип коннекта Qt::QueuedConnection поставить. Может там в функции, вызывающей сигнал ещё после него обращения к объектам идёт и из-за тог, что они уже не существуют всё накреняется.
Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #4 : Июнь 25, 2011, 22:04 »

попробуйте для этого сигнала тип коннекта Qt::QueuedConnection поставить. Может там в функции, вызывающей сигнал ещё после него обращения к объектам идёт и из-за тог, что они уже не существуют всё накреняется.
Проканало, благодарствую. Но всё равно не понимаю почему так работает. Если бы знал, что QLineEdit завязан на момент испускания сигнала с кем-то ещё, то и сам изначально этот тип сигнала бы указал. Но ведь ни он, ни qpushbutton, к которому этот же слот вешаю (без queuedconnection и работает) ни с кем больше не завязаны.
Кстати, valgrind ругался:
Код:
Invalid read of size 4
at 0x04c2b2cd: QMetaObject::activate(QObject*, QMetaObject const*, int, void**) (in /usr/lib/libQtCore.so.4.7.2)
by 0x0485b706: QLineControl::editingFinished() (in /usr/lib/libQtGui.so.4.7.2)
by 0x045d2498: QLineControl::processKeyEvent(QKeyEvent*) (in /usr/lib/libQtGui.so.4.7.2)
by 0x045c65e7: QLineEdit::keyPressEvent(QKeyEvent*) (in /usr/lib/libQtGui.so.4.7.2)
Address 0x9458894 is 4 bytes inside a block of size 132 free'd
at 0x04025907: operator
by 0x0485bb81: ??? (in /usr/lib/libQtGui.so.4.7.2)
by 0x045cd4af: ??? (in /usr/lib/libQtGui.so.4.7.2)
by 0x04c2d3ef: QObject::~QObject() (in /usr/lib/libQtCore.so.4.7.2)

« Последнее редактирование: Июнь 25, 2011, 22:08 от serg_hd » Записан

kubuntu/Win7/x64/NetBeans
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #5 : Июнь 26, 2011, 00:43 »

Проканало, благодарствую. Но всё равно не понимаю почему так работает. Если бы знал, что QLineEdit завязан на момент испускания сигнала с кем-то ещё, то и сам изначально этот тип сигнала бы указал.
Если посмотреть исходники, то внутри QLineEdit используется QLineControl.

Код
C++ (Qt)
   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;
   }

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;
    }
что черевато.
Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #6 : Июнь 26, 2011, 03:41 »

до просмотра исходников реализации QLineEdit'а доходить не решился, но со стороны его разработчиков не упомянуть такого в документации (рекомендацию использовать queuedconnection при сигнале returnPressed()), по-моему, не есть хорошо.
« Последнее редактирование: Июнь 26, 2011, 03:47 от serg_hd » Записан

kubuntu/Win7/x64/NetBeans
BRE
Гость
« Ответ #7 : Июнь 26, 2011, 04:09 »

до просмотра исходников реализации QLineEdit'а доходить не решился, но со стороны его разработчиков не упомянуть такого в документации (рекомендацию использовать queuedconnection при сигнале returnPressed()), по-моему, не есть хорошо.
Просто не стоит в слотах разрушать объект инициирующий выполнение этого слота! Для этого лучше воспользоваться специальным методом deleteLater().
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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