Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: aviabunin от Октября 06, 2011, 20:38



Название: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: aviabunin от Октября 06, 2011, 20:38
Хотелось бы сделать 2 режима использования клавиш -> <- (т.е. стрелок) в QTableWidget
1. Обычное перемещение по таблице
2. Выполнение спец функций по этим клавишам , при сохранении позиции в данной ячейке.
Спасибо за любую подсказку или ссылку.


Название: Re: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: kambala от Октября 06, 2011, 20:58
переопределить keyPressEvent(QKeyEvent *e) в наследнике QTableWidget и там, в зависимости от текущего режима, вызывать или не вызывать реализацию базового класса QTableWidget::keyPressEvent(e) (очевидно, что вызывать нужно для режима 1)


Название: Re: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: aviabunin от Октября 06, 2011, 21:13
А могу ли я что-то сделать не в наследнике QTableWidget, а в Ui::MainWindow.
Там я перехватываю нажатие клавиши и что-то делаю, скажем меняю цвет ячейки.
Нельзя ли в  обработке прерывания от клавиши - прямо установить текущей ячейку с заданными
номером столбца и строки? Например, если нажата клавиша вправо - уменьшить на 1 номер текущего столбца?
Код в приложении.
PS. Приложение простое - на главной форме в дизайнере - таблица.
     На ней VerticalLayout - на нем рисую.
Как мне перехватывать нажатие клавиши от этой таблицы?

Я сделаю наследование от таблицы - но немного побаиваюсь , что не сразу получится - а время ограничено.


Название: Re: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: iroln от Октября 06, 2011, 21:41
Вы можете установить фильтр событий с помощью installEventFilter и перехватывать нужное событие до того как оно дойдёт до таблицы. Это лучший вариант чем наследование и переопределение обработчика события.
Установка фильтров событий происходит на уровне объектов, что даёт возможность вместо наследования класса использовать объект фильтра.

Код:
my_table.installEventFilter(this)

затем вы определяете в своём классе окна виртуальный метод eventFilter и в нём перехватываете событие для объекта таблицы.

Почитайте доку или книжку Макса Шлее, там всё написано подробно.


Название: Re: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: kambala от Октября 06, 2011, 21:51
ох, страшноватый код... :) в данном случае в главном окне наверное даже лучше пользоваться eventFilter() и в нем обрабатывать событие QEvent::KeyPress чем keyPressEvent() (о, выше как раз и подсказали как именно это сделать).

в наследовании нету ничего страшного - помимо переопределения нужного метода просто описываешь стандартный конструктор, вызывающий родительский.


Название: Re: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: aviabunin от Октября 06, 2011, 22:03
Я прошу прощения по наследованию вопрос.
У меня есть таблица на главном окне в дизайнере.
Что в данном случае нужно сделать - убрать из дизайнера и определить свой класс и положить
его на mainwindow? Или что?


Название: Re: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: kambala от Октября 06, 2011, 22:13
нет, убирать не нужно. надо в дизайнере нажать на него правой кнопкой - promote to - и там выбрать унаследованный класс.


Название: Re: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: aviabunin от Октября 07, 2011, 08:39
К сожалению установил русифированную версию (как оказалось зря, но переустанавливать руки не доходят).
Правильно ли я понял : я встаю на таблицу , правой кнопкой - выбираю преобразовать в , скажем myTable.
Вроде создается класс , но где увидеть его код? Не  понимаю ...


Название: Re: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: aviabunin от Октября 07, 2011, 09:07
По фильтрy:
Я сделал в
Код:
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
...
    QObject::connect(ui->tableWidget, SIGNAL(currentCellChanged(int,int,int,int)), this, SLOT(MyEventHandler()));
    ui->tableWidget->installEventFilter(this);

}
И определил обработчик события:
Код:
void MainWindow::eventFilter(QObject tablica,QKeyEvent *event){

    if (event->key() == Qt::Key_Right)
    {
      //Ничего не делаю - в т.ч. не перемещаюсь
    }
    else if (event->key() == Qt::Key_Left)
    {
      // ...
    }
    else{}
        //QTableWidget::keyPressEvent(event);   и дальше событие не передаю
}
Я ожидал, что таким образом отменю перемещение по стрелкам -> <-.
Что не так?


Название: Re: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: kambala от Октября 07, 2011, 09:14
Правильно ли я понял : я встаю на таблицу , правой кнопкой - выбираю преобразовать в , скажем myTable.
Вроде создается класс , но где увидеть его код? Не  понимаю ...
да, правильно. класс не создается - ты должен указать свой существующий класс. пример (см. скрин и код):
Код
C++ (Qt)
// d2stringtablewidget.h
class D2StringTableWidget : public QTableWidget { ... }
По фильтрy:
почитай в документации как работать с eventFilter


Название: Re: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: aviabunin от Октября 07, 2011, 10:00
Я прошу прощения, все равно не совсем понимаю.
Откуда берется "мой существующий класс". Я , конечно, могу его создать сам - Из контекстного меню проекта выбрать добавить новый класс , там же указывается
базовый , скажем , QtableWidget. А потом добавить его на форму?


Название: Re: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: kambala от Октября 07, 2011, 10:25
да, создаешь класс, а на форму добавляешь QTableWidget и его "преобразовать в" созданный класс


Название: Re: Как отменить перемещение по QTableWidget по стрелкам
Отправлено: iroln от Октября 07, 2011, 14:00
Я ожидал, что таким образом отменю перемещение по стрелкам -> <-.
Что не так?
Чтобы событие не доходило до объекта, для которого установлен фильтр, функция eventFilter должна возвращать true.

Код:
bool MainWindow::eventFilter(QObject obj, QEvent *event){
    
    // Так же нужна проверка на то, что в данный момент события фильтруются для нужного объекта
   // ...

    if (event->type() != QEvent::KeyPress) {
       return false;
    }

    if (event->key() == Qt::Key_Right)
    {
      //Ничего не делаю - в т.ч. не перемещаюсь
      return true;
    }
    else if (event->key() == Qt::Key_Left)
    {
      // ...
      return true;
    }
    else {
      // передаю событие дальше
      return false;
    }
}

Код:
tablica
Никогда так не пишите - это называется говнокод. :)