Russian Qt Forum
Октябрь 02, 2024, 15:28 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: textEdited для QTextEdit'a  (Прочитано 8657 раз)
blood_shadow
Гость
« : Октябрь 17, 2011, 17:33 »

Добрый день,
Есть такой полезный метод для QLineEdit textEdited(), как сделать такое же для QTextEdit или для его QTextDocument()
textChanged() не подходить, он генерируется и при QTextEdit::setText(), мне нужно чтобы сигнал генерировался
только когда пользователь редактировал.

Спасибо
Записан
blood_shadow
Гость
« Ответ #1 : Октябрь 20, 2011, 13:46 »

Короче ненашел я ничего подходящего и склепал свою реализацию textEdited() для QTextEdit,
все это красиво обернуто в класс от которого можно унаследоваться:
Код
C++ (Qt)
#include <QtGui/QTextEdit>
 
class AbstractFileModel;
 
class AbstractFileView : public QTextEdit
{
   Q_OBJECT
 
public:
   AbstractFileView(QWidget *parent = 0);
   virtual ~AbstractFileView() = 0;
 
protected:
   void keyPressEvent(QKeyEvent *keyEvent);
   void insertFromMimeData(const QMimeData *source);
 
signals:
   void textEdited();
 
};
 
// *** and realization ***
 
AbstractFileView::AbstractFileView(QWidget *parent)
   : QTextEdit(parent)
{
}
 
AbstractFileView::~AbstractFileView()
{
}
 
void AbstractFileView::insertFromMimeData(const QMimeData *source)
{
   if (canInsertFromMimeData(source))
   {
       QTextEdit::insertFromMimeData(source);
       emit textEdited();
   }
}
 
void AbstractFileView::keyPressEvent(QKeyEvent *keyEvent)
{
   if (keyEvent->key() == Qt::Key_V )
   {
       if (keyEvent->modifiers() == Qt::ControlModifier)
       {
           QTextEdit::keyPressEvent(keyEvent);
           return;
       }
   }
 
   QTextEdit::keyPressEvent(keyEvent);
 
   switch (keyEvent->key())
   {
 
   case Qt::Key_Control:
   case Qt::Key_Shift:
   case Qt::Key_Alt:
   case Qt::Key_AltGr:
   case Qt::Key_Meta:
       return;
 
   default:
   {
       if (keyEvent->modifiers() == Qt::ControlModifier)
           return;
 
       emit textEdited();
   }
 
   }
 
}
 
 

Если есть какие-то предложения по улучшению или нашли ошибки - пишите я буду только рад  Улыбающийся
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4744



Просмотр профиля WWW
« Ответ #2 : Октябрь 20, 2011, 15:17 »

какое-то странное название класса ты дал - из него нельзя догадаться, что в него можно текст вводить

судя по реализации, если я нажму кнопку перемещения (стрелки, Page Up, Page Down, Home, End), то сигнал тоже будет отправлен

не вижу особого смысла выделять комбинацию Ctrl+V, если у тебя и так все нажатия с контролом не отправляют сигнал
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
blood_shadow
Гость
« Ответ #3 : Октябрь 20, 2011, 15:44 »

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

я не настаиваю на лицензии, изменять можно как угодно  Улыбающийся

Цитировать
судя по реализации, если я нажму кнопку перемещения (стрелки, Page Up, Page Down, Home, End), то сигнал тоже будет отправлен

это было влом разбираться что может привести к редактированию, а что нет, пока времени нет,
потом допилю

Цитировать
не вижу особого смысла выделять комбинацию Ctrl+V, если у тебя и так все нажатия с контролом не отправляют сигнал

а тут как раз смысл есть, модификаторы нажаты "сами по себе" не отправляют сигнал, но если
нажат любой другой модификатор (только не Ctrl), и при удерживании его поступает нажатие любой
другой клавиши то комбинация выпускает сигнал,

сами по себе сочетания ctrl + "any Key" не дают модификации, в отличии от shift + "any Key"
or alt+ "any Key", но тут есть особый случай ctrl + V, который дает модификацию, но эта
комбинация вызывает insertFromMimeData() в которой и эмитится сигнал

Надеюсь ясно выразился  Улыбающийся
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #4 : Октябрь 22, 2011, 13:19 »

Есть предложения. Читать доку.
http://doc.qt.nokia.com/latest/qtextdocument.html#modified-prop
Или даже http://doc.qt.nokia.com/stable/qtextdocument.html#contentsChanged
Чтоб совсем не изобретать ласипед.
« Последнее редактирование: Октябрь 22, 2011, 13:21 от Авварон » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Октябрь 22, 2011, 14:47 »

Мне кажется велосипед сконструирован неверно. Лезть в разборки клавиш и всевозможных комбинаций - дело гиблое, сколько не допиливай. Я бы попытался "одеть" вызовы setText в какую-то оболочку.

Есть предложения. Читать доку.
...
Чтоб совсем не изобретать ласипед.
Читать конечно надо, никто не спорит. Но есть опасность слишком уж увлечься чтением  Улыбающийся
Записан
blood_shadow
Гость
« Ответ #6 : Октябрь 22, 2011, 17:41 »

Есть предложения. Читать доку.
http://doc.qt.nokia.com/latest/qtextdocument.html#modified-prop
Или даже http://doc.qt.nokia.com/stable/qtextdocument.html#contentsChanged
Чтоб совсем не изобретать ласипед.

пробовал я эти все варианты, но они не работают, к примеру ф-ция setText() вызывает сигнал textChanged()
если прицепить этот сигнал к слоту, например вот так:
Код
C++ (Qt)
connect(ui.textEdit->document(), SIGNAL(textChanged()), SLOT(modifiedByUser()));
и определить слот вот так:
Код
C++ (Qt)
void TextEdit::modifiedByUser()
{
   if (ui.textEdit->document()->isModified())
       qDebug() << "Modified by user";
   else
       qDebug() << "Modified by program";
}
 

то не важно при модифицировании пользователем, то ли при вызове setText(), всеравно мы получим "Modified by user"
qt 4.7.3
Записан
blood_shadow
Гость
« Ответ #7 : Октябрь 22, 2011, 17:44 »

Мне кажется велосипед сконструирован неверно. Лезть в разборки клавиш и всевозможных комбинаций - дело гиблое, сколько не допиливай. Я бы попытался "одеть" вызовы setText в какую-то оболочку.
setText всеравно генерирует textChanged() как огда различать это был пользователь или программа?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Октябрь 22, 2011, 17:50 »

setText всеравно генерирует textChanged() как огда различать это был пользователь или программа?
С помощью "оболочки" Вы сможете знать "откуда". 
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #9 : Октябрь 22, 2011, 23:23 »

QObject::blockSignals или как-то так.
Записан
blood_shadow
Гость
« Ответ #10 : Октябрь 22, 2011, 23:38 »

QObject::blockSignals или как-то так.
помойму, это не покатит, эдит же у нас один, а если мы заблочим сигналы, то произойдет:
Код:
If block is true, signals emitted by this object are blocked (i.e., emitting a signal will not invoke anything connected to it).

то есть не при редактировании, не при setText() вообще никакого textChanged() не будет,
или я что-то не понял?
Записан
blood_shadow
Гость
« Ответ #11 : Октябрь 22, 2011, 23:39 »

setText всеравно генерирует textChanged() как огда различать это был пользователь или программа?
С помощью "оболочки" Вы сможете знать "откуда". 
небольшой пример в студию...
ибо я знаю только sender() а он будет одинаковым для одного и того же текст эдита
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Октябрь 23, 2011, 09:14 »

Неплохо и с blockSignals
Код
C++ (Qt)
void MySetText( QEditText & eText, const QString & str )
{
eText.blockSignals(true);
eText.setText(str);
eText.blockSignals(false);
}
 
А можно и так
Код
C++ (Qt)
void MyEditText::DoSetText( const QString & str )
{
mFlagSetText = true;
setText(str);
mFlagSetText = false;
}
 
А в слотe привести sender'а к MyEditText и посмотреть его флаг 
небольшой пример в студию...
Лучше сказать "а можно пример?"
Записан
blood_shadow
Гость
« Ответ #13 : Октябрь 23, 2011, 17:34 »

Неплохо и с blockSignals
Код
C++ (Qt)
void MySetText( QEditText & eText, const QString & str )
{
eText.blockSignals(true);
eText.setText(str);
eText.blockSignals(false);
}
 

спасибо, сделал так  Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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