Russian Qt Forum

Qt => Вопросы новичков => Тема начата: sergey_t от Август 07, 2014, 10:25



Название: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: sergey_t от Август 07, 2014, 10:25
Здравствуйте, прошу помощи у знатоков.
Пишу прогу в Linux (Lubuntu). Qt 5.3.1
В виджетах для ввода/редактирования текста (например в QPlainTextEdit) в русской раскладке не работают сочетания Ctrl+C/Ctrl+V и прочие стандартые. В US раскладке всё хорошо, а в русской приходится только через контекстное меню.
Как исправить? ???


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: Hrundel от Август 09, 2014, 10:15
Ищи как получить шестнадцатиричное значение key в русской раскладке, а потом пиши вместо Qt::Key_Control + Qt::Key_C что-то типа Qt::Key_Control + 0x01001103

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    qDebug() << event->key();
}

В данном случае event->key(); возвращает код как int.


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: kambala от Август 09, 2014, 12:52
keyEvent->native...()


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: Hrundel от Август 09, 2014, 15:24
keyEvent->native...()

Ну, вот, благодаря kambala нашлась и функция:  :)

Код
C++ (Qt)
quint32 QKeyEvent::nativeVirtualKey () const


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: sergey_t от Август 09, 2014, 20:22
Спасибо за советы, но только я не как не работаю в коде с событиями, никакие шорткаты специально не назначаю, у меня просто дефолтный QPlainTextEdit, у него по-умолчанию есть контекстное меню с копированием/вставкой и пр. Пробовал назначить свои шорткаты (кстати можно и без перевода клавиши в число, работать будет в обоих раскладках), но это какое-то слишком уж топорное решение (придётся заново назначить все действия всё-таки). Выход конечно, но без этого никак не сделать?

+ у меня не одно поле редатирования, несколько форм, много QLineEdit, это для каждого в ручную переназначать экшены? ужос :'(

а нельзя ли как-то перехватить и перевести коды клавиш в конструкторе формы, например, чтобы автоматом везде заработало?


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: Hrundel от Август 10, 2014, 01:04
Ну, keyPressEvent  для каждой формы, хочешь ни хочешь - придется переопределять. Написать в каком-то классе один метод на все формы, и переводить на него.
сделать switch для комбинаций. Но коды шестнадцатиричные, все-равно, сначала вручную для нужных клавиш собирать придется.
Других решений не вижу.


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: lit-uriy от Август 10, 2014, 09:31
sergey_t Это может происходить из-за ошибочного перевода сочетания клавиш в файле перевода qt_ru.ts
попробуй поискать там в контексте соответствующих виджетов. Лучше всего чтобы перевода для них просто не было.


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: Igors от Август 10, 2014, 09:52
Повесить фильтр на QApplication - или перекрыть его notify. Там отловить QEvent::KeyPress и подменить его. Если понадобится - и QEvent::ShortcutOverride


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: sergey_t от Август 10, 2014, 10:11
Спасибо всем за помощь, проблема решена :)
Выкладываю код, может кому пригодится.

1) Создаём класс, перехватывающий нажатия клавиш и делающий "перевод" (через искусственное создание событий) для Ctrl+C/ Ctrl+V и других стандартных шорткатов:

======= keytranslator.h ========

Код:
#ifndef KEYTRANSLATOR_H
#define KEYTRANSLATOR_H

#include <QApplication>
#include <QtGui>

class KeyTranslator : public QObject {
    protected:
    bool eventFilter(QObject* pobj, QEvent* pe){
        if (pe->type() == QEvent::KeyPress) {

            // for copy

            if (((QKeyEvent*)pe)->modifiers() == Qt::CTRL && ((QKeyEvent*)pe)->key() == 1057) {
                QKeyEvent* pe = new QKeyEvent(QEvent::KeyPress,
                                              Qt::Key_C,
                                              Qt::ControlModifier,
                                              ""
                                              );
                QApplication::sendEvent(pobj, pe);
                return true;
            }

            // for cut

            if (((QKeyEvent*)pe)->modifiers() == Qt::CTRL && ((QKeyEvent*)pe)->key() == 1063) {
                QKeyEvent* pe = new QKeyEvent(QEvent::KeyPress,
                                              Qt::Key_X,
                                              Qt::ControlModifier,
                                              ""
                                              );
                QApplication::sendEvent(pobj, pe);
                return true;
            }

            // for paste

            if (((QKeyEvent*)pe)->modifiers() == Qt::CTRL && ((QKeyEvent*)pe)->key() == 1052) {
                QKeyEvent* pe = new QKeyEvent(QEvent::KeyPress,
                                              Qt::Key_V,
                                              Qt::ControlModifier,
                                              ""
                                              );
                QApplication::sendEvent(pobj, pe);
                return true;
            }



            // for redo

            if (((QKeyEvent*)pe)->modifiers() == Qt::CTRL + Qt::SHIFT && ((QKeyEvent*)pe)->key() == 1071) {
                QKeyEvent* pe = new QKeyEvent(QEvent::KeyPress,
                                              Qt::Key_Z,
                                              Qt::ControlModifier | Qt::ShiftModifier,
                                              ""
                                              );
                QApplication::sendEvent(pobj, pe);
                return true;
            }

            // for undo

            if (((QKeyEvent*)pe)->modifiers() == Qt::CTRL && ((QKeyEvent*)pe)->key() == 1071) {
                QKeyEvent* pe = new QKeyEvent(QEvent::KeyPress,
                                              Qt::Key_Z,
                                              Qt::ControlModifier,
                                              ""
                                              );
                QApplication::sendEvent(pobj, pe);
                return true;
            }

            // for select all

            if (((QKeyEvent*)pe)->modifiers() == Qt::CTRL && ((QKeyEvent*)pe)->key() == 1060) {
                QKeyEvent* pe = new QKeyEvent(QEvent::KeyPress,
                                              Qt::Key_A,
                                              Qt::ControlModifier,
                                              ""
                                              );
                QApplication::sendEvent(pobj, pe);
                return true;
            }

        }

    return false;
    }
public:
    KeyTranslator(QObject* pobj = 0) : QObject(pobj)
    {
    }
};

#endif // KEYTRANSLATOR_H

===================

2) в mainwindow.h добавляем
Код:
#include "keytranslator.h"
3) в mainwindow.h в секции private добавляем
Код:
KeyTranslator*  keyTranslator;
4) подключаем в конструкторе в mainwindow.cpp
Код:
keyTranslator = new KeyTranslator(ui->plainTextEdit);
ui->plainTextEdit->installEventFilter(keyTranslator);

Далее, где нам нужно можем методом installEventFilter подключить к любому полю редактирования, включая QLineEdit


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: Igors от Август 10, 2014, 10:42
Код:
class KeyTranslator : public QObject {
            // for copy

            if (((QKeyEvent*)pe)->modifiers() == Qt::CTRL && ((QKeyEvent*)pe)->key() == 1057) {
...
            // for cut

            if (((QKeyEvent*)pe)->modifiers() == Qt::CTRL && ((QKeyEvent*)pe)->key() == 1063) {
... 
            // for paste
Это называется "не ленивый программист" :) А что будет с др раскладкой клавы? Лучше так
Код
C++ (Qt)
QKeyEvent * MyTranslateKeyEvent( const QKeyEvent * ке )
{
 static QMap <quint32, int> theMap;  // virtual key + key
 if (!theNap.size()) {
  theMap[VKEY_A] = Qt::Key_A;   // VKEY_A найдете в отладчике
  theMap[VKEY_С] = Qt::Key_С;
  ...
 }
 
 if (ke->type() != Qt::KeyPress) return 0;
 if (ke->modifiers() != Qt::CTRL) return 0;
 int newKey = theMap.value(ke->nativeVirtualKey();
 if (!newKey || newKey == ke->key()) return 0;
 return new QKeyEvent(QEvent::KeyPress, newKey,  Qt::ControlModifier);
}
 
Далее, где нам нужно можем методом installEventFilter подключить к любому полю редактирования, включая QLineEdit
Путь события

QApplication::notify
фильтры на  QApplication
фильтры на  объекте-приемнике
объект-приемник

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


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: sergey_t от Август 10, 2014, 11:19
TO:Igors

Спасибо за совет, учту


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: navrocky от Август 10, 2014, 11:28
на мой взгляд надо чинить твою операционку а не программу. ни с одной версией qt ни под одной ОС такого не наблюдал. а так костылей можно много на городить, причем они еще будут и побочные эффекты давать на рабочих системах


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: sergey_t от Август 10, 2014, 11:32
на мой взгляд надо чинить твою операционку а не программу. ни с одной версией qt ни под одной ОС такого не наблюдал. а так костылей можно много на городить, причем они еще будут и побочные эффекты давать на рабочих системах

Согласен, но если бы ещё знать что чинить


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: navrocky от Август 10, 2014, 15:44
Согласен, но если бы ещё знать что чинить

Ну на крайняк переустановить операционку ;) Возможно и в других Qt прогах у вас будет наблюдаться такие глюки, но там уже их не исправить.


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: qate от Август 18, 2014, 14:42
это баг https://bugreports.qt-project.org/browse/QTCREATORBUG-9589
временно чинится как там указано


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: lit-uriy от Август 18, 2014, 16:37
qate, там речь про креатор, а не про Qt


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: qate от Август 21, 2014, 11:26
qate, там речь про креатор, а не про Qt

креатор на чём написан ? )


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: juvf от Март 25, 2015, 13:49
на мой взгляд надо чинить твою операционку а не программу. ни с одной версией qt ни под одной ОС такого не наблюдал. а так костылей можно много на городить, причем они еще будут и побочные эффекты давать на рабочих системах
Это косяк Qt5.*. У меня  QTextEdit - такая же проблема. На Win7 и на Win XP. Пятерка спортила некогда годный фреймворк.

Запустил из демок  в Qt5.4.0 пример TextEdit - всё работает. посмотрел исходники.... к Ctrl+C (+V) прикручены экшены Copy(Past). Поэтому в примере, в редакторе текста, всё работает. Поставьте курсор на редактирование имени шрифта и этоже проге - в английской раскладке копи-паст работает, в русской нет.
Закоментируйте в сырцах строчки 257, 263 (a->setShortcut(QKeySequence::Copy); ....) и в центральном виджете QTextEdit перестанет работать копи-паст в русской раскладке.

Запускаю TextEdit из QDemo от Qt4.8. В 4-ке в редактировании шрифта работает и русский и английский копипаст.


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: gil9red от Март 25, 2015, 14:43
на мой взгляд надо чинить твою операционку а не программу. ни с одной версией qt ни под одной ОС такого не наблюдал. а так костылей можно много на городить, причем они еще будут и побочные эффекты давать на рабочих системах
Закоментируйте в сырцах строчки 257, 263 (a->setShortcut(QKeySequence::Copy); ....) и в центральном виджете QTextEdit перестанет работать копи-паст в русской раскладке.

Стоп-стоп-стоп! Не нужно в исходниках ничего комментировать :)


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: juvf от Март 25, 2015, 15:01
Стоп-стоп-стоп! Не нужно в исходниках ничего комментировать :)
Почему не надо? Они на то и даны, чтоб смотреть/использовать/модифицировать.

создайте свой хеловорд с QTextEdit и проверьте


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: __Heaven__ от Март 25, 2015, 15:35
А есть способ решения проблемы до выхода исправления? У меня нет экшенов на копипаст.


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: gil9red от Март 25, 2015, 15:41
Стоп-стоп-стоп! Не нужно в исходниках ничего комментировать :)
Почему не надо? Они на то и даны, чтоб смотреть/использовать/модифицировать.

создайте свой хеловорд с QTextEdit и проверьте

Какой хеловорд... я про исходники qt говорил, а вы?


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: juvf от Март 25, 2015, 15:47
Какой хеловорд... я про исходники qt говорил, а вы?
Я не про исходники Qt говорил. Я говорил про исходники QDemo, или экзамплов. В частонсти про пример TextEdit. Если кто-то боиться испортить оригинальный пример.... то во первых можно копию примера сделать и проверить, во вторых оригинал примера есть в асистенте, в третих оригинал всегда можно скачать из инета, с qt.io


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: juvf от Март 25, 2015, 15:52
А есть способ решения проблемы до выхода исправления? У меня нет экшенов на копипаст.
Есть. Я так исправил, спасибо sergey_t

Его KeyTranslator (http://www.prog.org.ru/index.php?topic=27424.msg198957#msg198957) закинь в KeyTranslator.h

в main.cpp делаем так

Код:
#include "main.h"
#include "MainWindow.h"
#include "KeyTranslator.h"

#include <QApplication>

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
  
    KeyTranslator *keyTranslator = new KeyTranslator();
    app.installEventFilter(keyTranslator);
  
    MainWindow w;
    w.show();

    return app.exec();
    delete keyTranslator;//не обязательно
}
Теперь во всех виджетах работает русский копи-паст


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: PimenS от Март 25, 2015, 15:59
В 5.4.1 на винде, этого бага уже нет.


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: __Heaven__ от Март 25, 2015, 15:59
Я невнимательный. Не заметил сообщения от sergey_t. Спасибо.


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: juvf от Март 25, 2015, 16:01
В 5.4.1 на винде, этого бага уже нет.
спасибо, попробую обновиться.


Название: Re: Не работают Ctrl+C и Ctrl+V в русской раскладке в виджетах редактирования
Отправлено: __Heaven__ от Март 25, 2015, 16:07
В 5.4.1 на винде, этого бага уже нет.
Проверил. Подтверждаю.