Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: xintrea от Май 30, 2009, 22:23



Название: QTextEdit - как поймать моменты Undo/Redo и сделать дополнительные действия?
Отправлено: xintrea от Май 30, 2009, 22:23
Здравствуйте!


Есть у меня объект QTextEdit. Нужно сделать так, что в моменты когда пользователь делает Undo/Redo (например, нажимает Ctrl+Z), вызывался слот, в котором я смогу дополнительно выполнить нужные действия.

Читаю доку по QTextEdit, вижу что есть слоты undo() и redo(). Но что-то не могу понять, как ими пользоваться? Если бы это были сигналы, я бы их законнектил с самописным слотом, и задача была б решена. Но это слоты! Что с ними делать?

Есть мысля унаследоваться от QTextEdit, и переопределить слоты undo() и redo(). Но тогда возникает вопрос - а будет ли в этом случае работать отмена/повтор редактирования? Ведь мне нужно не заменить код отмены/повтора, а "дополнить" его.


Вопрос - как правильно ловить момент вызова пользователем Undo/Redo? Может быть можно как-то через события? Что-то не нашел такого. Может есть еще какой-то способ?


Название: Re: QTextEdit - как поймать моменты Undo/Redo и сделать дополнительные действия?
Отправлено: Авварон от Май 30, 2009, 23:37
если наследоваться то в новом методе делай QTextEdit::undo();


Название: Re: QTextEdit - как поймать моменты Undo/Redo и сделать дополнительные действия?
Отправлено: Valeriy от Май 30, 2009, 23:37
void MyClass::keyPressEvent(QKeyEvent * event) {
   if (event->modifiers().testFlag(Qt::ControlModifier) && event->key()== Qt::Key_Z){
      // ........
   }
   QTextEdit::keyPressEvent(event); // Вызов метода родителя.
}

Вроде должно работать.

Можно попробовать сделать то же самое и со слотом undo, но так как он был введён только в qt4.2, то возможно он просто дёргает какую-то внутреннюю функцию, а не вызывается каждый раз, когда происходит undo.


Название: Re: QTextEdit - как поймать моменты Undo/Redo и сделать дополнительные действия?
Отправлено: xintrea от Май 31, 2009, 00:05
если наследоваться то в новом методе делай QTextEdit::undo();

Да вот унаследовался, undo работает (на экране идёт отмена). А вот слот undo() в производном от QTextEdit классе не вызывается.

Непойму почему. Точнее, не пойму, как сделать чтоб слот undo() вызывался? По идее, он автоматом должен вызываться, но может что-то законнектить надо? В любом случае непонятно, почему слот undo() не вызывается, а на экране undo работает какнада.

Заголовок
Код:
// Промежуточный класс QTextEdit, созданный чтобы можно было работать
// с механизмом undo/redo
class EditorTextEdit : public QTextEdit
{
 Q_OBJECT

public:
 EditorTextEdit(QWidget * parent);
 ~EditorTextEdit();

public slots:
 void undo();
 void redo();

signals:
 void undo_running();
 void redo_running();

};

Реализация
Код:
EditorTextEdit::EditorTextEdit(QWidget * parent = 0) : QTextEdit(parent)
{ }

EditorTextEdit::~EditorTextEdit()
{ }

void EditorTextEdit::undo()
{
 QTextEdit::undo();
 qDebug() << "Undo running";
 emit undo_running();
}

void EditorTextEdit::redo()
{
 QTextEdit::redo();
 qDebug() << "Redo running";
 emit redo_running();
}

Как видно, в момент отмены, в консоль как минимум должно печататься сообщение "Undo running". Но этого не происходит. И еще, если закомментировать QTextEdit::undo(); , то отмена всёравно работает.

Видимо я всётаки не догнал, как пользоваься и переопределять готовые слоты в Qt.

Что я сделал неправильно?


Название: Re: QTextEdit - как поймать моменты Undo/Redo и сделать дополнительные действия?
Отправлено: Valeriy от Май 31, 2009, 00:57
"Можно попробовать сделать то же самое и со слотом undo, но так как он был введён только в qt4.2, то возможно он просто дёргает какую-то внутреннюю функцию, а не вызывается каждый раз, когда происходит undo."

Код:
void EditorTextEdit::keyPressEvent(QKeyEvent * event) {
   if (event->modifiers().testFlag(Qt::ControlModifier) && event->key()== Qt::Key_Z){
      qDebug() << "Undo running";
   }
   QTextEdit::keyPressEvent(event); // Вызов метода родителя.
}

Работает


Название: Re: QTextEdit - как поймать моменты Undo/Redo и сделать дополнительные действия?
Отправлено: pastor от Май 31, 2009, 01:37
Да вот унаследовался, undo работает (на экране идёт отмена). А вот слот undo() в производном от QTextEdit классе не вызывается.

А с чего такая уверенность, что undo\redo должны вызываться?


Название: Re: QTextEdit - как поймать моменты Undo/Redo и сделать дополнительные действия?
Отправлено: spectre71 от Май 31, 2009, 09:53
1) Как было отмечено выше QTextEdit::undo()/QTextEdit::redo() не обязательно вызываются самим QTextEdit при получении клавиатурных событий. Они скорее всего обертка над реальными вызовами для организации соединений.
2) QTextEdit::undo()/QTextEdit::redo() не являются ВИРТУАЛЬНЫМИ методами и даже если бы они вызывались в QTextEdit непосредственно ваше переопределение их в наследнике не будет вызвано, а будут вызваны QTextEdit::undo()/QTextEdit::redo()

Так что, как писалось выше, вам необходимо отлавливать нужные клавиатурные события и вызывать свои дополнительные обработчики, при этом не забывая передавать события предку(QTextEdit)


Название: Re: QTextEdit - как поймать моменты Undo/Redo и сделать дополнительные действия?
Отправлено: spectre71 от Май 31, 2009, 10:21
Кстати никогда не надо забывать что непосредственный вызов слота с точки зрения виртуального механизма, ничем не отличается от вызова любого другого метода!
Однако, вызов через сигнал всегда виртуальный даже если слот невиртуальный метод!


Название: Re: QTextEdit - как поймать моменты Undo/Redo и сделать дополнительные действия?
Отправлено: xintrea от Май 31, 2009, 12:11
Я понимаю, что отлавливая клавиатурнуе комбинации, можно ловить undo/redo. Но помимо этих комбинаций, команды undo/redo могут быть

- в меню,
- вызываться по кнопкам на экране,
- находится в контекстном меню.

И что, для каждого такого случая надо отдельно код дописывать чтоб обработку перехватить? Я думал что есть централизованное решние.


Название: Re: QTextEdit - как поймать моменты Undo/Redo и сделать дополнительные действия?
Отправлено: spectre71 от Май 31, 2009, 12:35
Ну а слоты для чего!