Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: maybell от Июль 17, 2008, 11:21



Название: как сохранить позицию anchor в QTextEdit?
Отправлено: maybell от Июль 17, 2008, 11:21

Необходимо запомнить позицию якоря в поле TextEdit и после неких манипуляций (например:выделение->вырезание->вставка текста) якорь должен встать на ту позицию, в которую был поставлен до этих операций.
В QT я новичок, удалось только расставить кнопки и настроить действия выделения, вырезки и вставки.
А вот как работать с курсором?
Копания в ассистенте не очень помогают

пробовались манипуляции типа

Код:
void Worktest::DragText()
{

QTextCursor *cursor=new QTextCursor();

//cursor->anchor();


//cursor->QTextCursor::movePosition(QTextCursor::EndOfBlock,QTextCursor::MoveAnchor,1);//**
cursor->QTextCursor::atEnd ();


//cursor-> getCursorPosition ();
//cursor-> movePosition (MoveAnchor,EndOfBlock mode = MoveAnchor, int n = 1 );

//text->textCursor();

text->cursorRect ();

но ничего не происходит..
может, кто-то поможет разобраться?

ps.Qt 4.1.2

worktest.h
http://www.everfall.com/paste/id.php?3dcdl96tggc6 (http://www.everfall.com/paste/id.php?3dcdl96tggc6)
worktest.cpp
http://www.everfall.com/paste/id.php?7tgbj0xls9ii (http://www.everfall.com/paste/id.php?7tgbj0xls9ii)
main.cpp
http://www.everfall.com/paste/id.php?n4g2c4kuzo96 (http://www.everfall.com/paste/id.php?n4g2c4kuzo96)


Название: Re: как сохранить позицию anchor в QTextEdit?
Отправлено: spirit от Июль 17, 2008, 12:12
вот простенький примерчик (немного поправил ваш пример):
Код:
Worktest::Worktest(QWidget *parent)
: QWidget(parent), m_cursorPosition(0)
{
     QFrame *frameout = new QFrame;
     frameout->setGeometry(QRect(0, 0, 100, 100));
     text = new QTextEdit(frameout);
text->setHtml("<html><body><p style=\" margin-top:0px; margin-bottom:0px;text-align:center; margin-left:20px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:20pt;\">Installation info:</p><p style=\" margin-top:0px; margin-bottom:20px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:20pt;\">Just copy smsrus.dll and smsrus.ini to your Miranda's plugins' directory.</p><p style=\" margin-top:0px; margin-bottom:20px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:20pt;\">Usage notes:</p><p style=\" margin-top:0px; margin-bottom:20px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:20pt;\">- To reload picture just recheck the same operator</p><p style=\" margin-top:0px; margin-bottom:20px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:20pt;\">- After sending message new picture is loaded automatically</p><p style=\" margin-top:0px; margin-bottom:20px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:20pt;\">- For debugging there are 2 parametrs in Options window,  showIE allows to show browser window  notSend allows not to send SMS when clicking the button, but fill all the fields INI file description:</p></body></html>");

     text->setGeometry(QRect(10, 10, 700, 300));
     QPushButton *button = new QPushButton(frameout);
     QPushButton *button2 = new QPushButton(frameout);
     QPushButton *button3 = new QPushButton(frameout);
     button->setText("Select");
     button2->setText("Cut");
     button3->setText("Paste");
     button->setGeometry(QRect(320, 320, 50, 20));
    button2->setGeometry(QRect(380, 320, 50, 20));
    button3->setGeometry(QRect(440, 320, 50, 20));   

     QVBoxLayout *layout = new QVBoxLayout;
     layout->addWidget(frameout);
     setLayout(layout);
    
     setWindowTitle(tr("Test WIDGET"));
     setMinimumSize(QSize(750, 550));
     setMaximumSize(QSize(750, 550));

  //QObject::connect(button, SIGNAL(clicked()), this, SLOT(close()));
     connect(button, SIGNAL(clicked()), this, SLOT(selectAll()));
     connect(button2, SIGNAL(clicked()), text, SLOT(cut()));
    connect(button3, SIGNAL(clicked()), this, SLOT(paste()));
}

void Worktest::selectAll()
{
m_cursorPosition = text->textCursor().anchor();
text->selectAll();
}

void Worktest::paste()
{
text->paste();
QTextCursor cur(text->textCursor());
cur.setPosition(m_cursorPosition);
text->setTextCursor(cur);
}
в ашнике добавил приватную переменную int m_cursorPosition;


Название: Re: как сохранить позицию anchor в QTextEdit?
Отправлено: Red Devil от Июль 17, 2008, 13:02
Это не так легко как кажется не первый вгляд.
Что нужно сделать чтобы установить курсор, например, в ситуации приведенной тобой (выделение->вырезание->вставка текста). Тебе нужно запомнить позицию начала выделения (selectionStart), перед вырезанием. Теперь наступает самое сложно - нужно во время действий пользователя узнавать смещение.
Ведь вставить текст пользователь может до/после той позиции, которая была выделена. Кроме того он еще может свой текст добавить/удалить, опять же и перед и после позиции курсора. Если после позиции курсора - то тебе это не помешает, а вот если до - то нужно изменить позицию якоря относительно того добавили ли символы или удалили их.

Для этого тебе наверное скорее всего подойдет сигнал :
Цитировать
void QTextDocument::contentsChange ( int position, int charsRemoved, int charsAdded )   [signal]
This signal is emitted whenever the document's content changes; for example, when text is inserted or deleted, or when formatting is applied.
Information is provided about the position of the character in the document where the change occurred, the number of characters removed (charsRemoved), and the number of characters added (charsAdded).
The signal is emitted before the document's layout manager is notified about the change. This hook allows you to implement syntax highlighting for the document.
See also QAbstractTextDocumentLayout::documentChanged() and contentsChanged()
Тебе нужно сравнить position с той position, которую ты сохранил и если меньша или равна, то соотвенно добавить к твоей позиции charsAdded и отнять от нее charsRemoved.


Название: Re: как сохранить позицию anchor в QTextEdit?
Отправлено: maybell от Июль 17, 2008, 13:54
вот простенький примерчик (немного поправил ваш пример):

Благодарю за пример, все прекрасно работает. По крайней мере так как пока необходимо)

Что нужно сделать чтобы установить курсор, например, в ситуации приведенной тобой (выделение->вырезание->вставка текста). Тебе нужно запомнить позицию начала выделения (selectionStart), перед вырезанием. Теперь наступает самое сложно - нужно во время действий пользователя узнавать смещение.
Ведь вставить текст пользователь может до/после той позиции, которая была выделена. Кроме того он еще может свой текст добавить/удалить, опять же и перед и после позиции курсора. Если после позиции курсора - то тебе это не помешает, а вот если до - то нужно изменить позицию якоря относительно того добавили ли символы или удалили их.

Спасибо за подсказку, буду над этим работать о_О