Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Редактирование, фокус, QTableView, Отменить окочание редактирования ячейки 
V
    Опции темы
TimberWolf
Дата 26.3.2012, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 6.1.2007
Где: Тула

Репутация: нет
Всего: нет



Здравствуйте! 
Имеется следующий вопрос. Есть свой виджет, наследованный от QLineEdit. Виджет представляет из себя собственно QLineEdit над которым появляется калькулятор при получении фокуса ввода. При нажатии на кнопки калькулятора, цифры вводятся в QLineEdit. Калькулятор унаследован от QDialog. Калькулятор немодальный, но всегда находится поверх QMainWindow.
Код

class CafeLineEdit : public QLineEdit {
    Q_OBJECT
public:
    CafeLineEdit(QWidget *parent = 0);
    void refreshCalcPos();
    ~CafeLineEdit();
protected:
    void mousePressEvent(QMouseEvent *);
    void resizeEvent(QResizeEvent *) { refreshCalcPos(); }
private slots:
    void calculatorClicked();
private:
    Ui::CalculatorWidget *calculator;
    QDialog *calculatorDialog;
    QValidator *validator;
};

Далее. Есть QTableView в котором данный виджет является виджетом редактирования(отдается делегатом). Но отредактировать значение в таблице с использованием данного виджета не получается из-за того, что при создании виджета, калькулятор автоматически получает фокус
Код

void CafeLineEdit::mousePressEvent(QMouseEvent *) {
    refreshCalcPos();
    calculatorDialog->show();
}

, а при потере фокуса ввода QTableView считает, что редактирование закончено и закрывает виджет редактирования. Получается, что калькулятор создается и тут же закрывается. Можно ли как-то решить эту проблему? Можно ли унаследоваться от QTableView и запретить прерывать редактирование при потере фокуса ввода? Либо, возможно, есть более элегантное решение?

Это сообщение отредактировал(а) TimberWolf - 26.3.2012, 18:23
PM MAIL Jabber   Вверх
_GRIN_
Дата 26.3.2012, 19:27 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


одинокий падаван
**


Профиль
Группа: Участник
Сообщений: 272
Регистрация: 18.11.2007
Где: Калуга

Репутация: 6
Всего: 7



я не уверен, но может стоит покопать в сторону setFocusProxy() ?


--------------------
Дорогу осилит идущий
PM MAIL Skype   Вверх
TimberWolf
Дата 26.3.2012, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 6.1.2007
Где: Тула

Репутация: нет
Всего: нет



Решение: необходимо унаследоваться от QTableView и перегрузить метод.
Код

void QAbstractItemView::closeEditor ( QWidget * editor, QAbstractItemDelegate::EndEditHint hint ) [virtual protected slot]

После чего QDialog перестанет пропадать, а при нажатии кнопки Закрыть в диалоге можно закрывать редактирование.

Это сообщение отредактировал(а) TimberWolf - 26.3.2012, 20:21
PM MAIL Jabber   Вверх
TimberWolf
Дата 27.3.2012, 00:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 6.1.2007
Где: Тула

Репутация: нет
Всего: нет



Вопрос вдогонку. Как внутри класса-потомка QTableView законнектить сигнал от виджета, который отдается делегатом, на свой слот? Не могу добраться до виджета, который отдается из метода createEditor() делегата.

Это сообщение отредактировал(а) TimberWolf - 27.3.2012, 00:25
PM MAIL Jabber   Вверх
math64
Дата 27.3.2012, 00:27 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Можно посмотреть на исходники Qt как там  сделан QComboBox и QDateEdit с календарём - нужно сделать аналогично.
PM   Вверх
TimberWolf
Дата 27.3.2012, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 6.1.2007
Где: Тула

Репутация: нет
Всего: нет



Цитата(_GRIN_ @ 26.3.2012,  19:27)
я не уверен, но может стоит покопать в сторону setFocusProxy() ?

Спасибо.
Код

void QWidget::setFocusProxy ( QWidget * w )

В итоге помог.
Изначально идея была следующая: сделать ввод в QLineEdit, используя либо калькулятор, который появляется над QLineEdit при клике на QLineEdit, либо обычную клавиатуру. Столкнулся с проблемой. При редактировании данных в таблице, кальтулятор получал фокус, и QTableView расценивал это как окончание редактирования и убивал калькулятор вместе с 
QLineEdit ( QLineEdit+калькулятор далее будем называть виджет-редактор. он отдается делегатом в QTableView). 
Варианты решений:
  • Унаследоваться от QTableView. Переопределить метод 
    Код

    void QAbstractItemView::closeEditor ( QWidget * editor, QAbstractItemDelegate::EndEditHint hint ) [virtual protected slot]
     в котором просто запрещать закрывать виджет-редактор. При этом возникнет проблема: виджет-редактор никогда не закроется. Но ее можно костыльно обойти. При создании делегата, создавать внутри него виджет-редактор и хранить ссылку на этот виджет-редактор и свой метод, который будет эту ссылку возвращать. Далее,  переопределить метод 
    Код
    void setItemDelegate ( QAbstractItemDelegate * delegate ) 
     в своем классе-наследнике от QTableView, в котором вызвать метод делегата(при этом еще придется сделать cast к вашему типу делегата), который отдает ссылку на виджет-редактор и сделать connect от калькулятора к собственному слоту, который вызовет настоящую функцию void QAbstractItemView::closeEditor.  Лютый, жуткий костыль.
  • Решение, имеющее место в моем случае. Калькулятор есть QWidget, который хранится в классе-наследнике QLineEdit. Инициализируется калькулятор следующим образом.
    Код

    CafeLineEdit::CafeLineEdit(QWidget *parent)
        : QLineEdit(parent) {
        calculatorWidget = new QWidget(0, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
        calculatorWidget->setWindowModality(Qt::ApplicationModal);
        calculator = new Ui::CalculatorWidget;
        calculator->setupUi(calculatorWidget);
        setFocusProxy(calculatorWidget);
        connect(calculator->panelButtonClose, SIGNAL(clicked()), this, SLOT(calculatorClosed()));
        ... остальной код

    Калькулятор будет находиться всегда сверху, будет без рамок и будет модальным. Модальным он может быть по вкусу. В моем случае это необходимо. Чтобы виджет-редактор при закрытии сказал QTableView о том, что ввод закончен, просто нажимаем клавишу Enter.
    Код

    void CafeLineEdit::calculatorClosed() {
        QKeyEvent keyRelease(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
        QApplication::sendEvent(this, &keyRelease);
    }

    Таким образом получаем рабочий виджет-редактор QLineEdit+калькулятор. Т.к мы делаем  setFocusProxy(calculatorWidget); то вводить цифры в наш LineEdit можно только из калькулятора, но не с клавиатуры. Для моей задачи это вполне подходит.
  •  Как посоветовал 
    Цитата(math64)
    Можно посмотреть на исходники Qt как там  сделан QComboBox и QDateEdit с календарём - нужно сделать аналогично. 
     Возможно в этом случае удастся сделать ввод как с помощью калькулятора, так и с помощью клавиатуры, если объединить их в одном компоненте.
Всем спасибо за подсказки!

Это сообщение отредактировал(а) TimberWolf - 27.3.2012, 18:54
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0746 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.