PDA

View Full Version : [Qt4] QTextEdit & cursor visibility



Ti_Thom
10th October 2006, 16:12
Hi,
i am writting a part of a widget that have to display a file and then highlight a line off this file.

The file is properly loaded and the wanted line highlighted but not visible : the QTextEdit widget does not scroll to the cursor position ...

the code is

//... doing things before ...
//show file
QTextEdit * editor = new QTextEdit(current_body_widget);
editor->setFocus();
{
QString file_to_view = QDir::cleanPath(QString("%1%2%3").arg(build_dir).arg(QDir::separator()).arg(fp.fil e));
QString error_str;
QFile file( file_to_view );
if ( !file.exists() ) {
error_str = QString( "%1 does not exist." ).arg( file_to_view );
}else{
if ( !file.open( QFile::ReadOnly | QFile::Text ) ) {
error_str = QString( "Cannot open %1" ).arg( file_to_view );
}
}
if(error_str.isEmpty()){
int nb_char=0;
int pos = 0;
int line = 0;
editor->setPlainText( QString("") );
QTextStream in(&file);

while(!in.atEnd()){
line++;
if(line == pi.line)
pos = nb_char;
QString line = in.readLine();
editor->append(line);
nb_char+= line.size() + 1; //+1 : '\n'
}

//moving cursor
QTextCursor text_cursor = editor->textCursor();
text_cursor.setPosition(pos);

text_cursor.select(QTextCursor::BlockUnderCursor);
editor->ensureCursorVisible();
editor->setTextCursor(text_cursor);
}
else
editor->setPlainText( error_str );
//editor->setReadOnly(true);
}

editor->update();
layout->addWidget(editor);
//... doing things after ...


What am i doing wrong ?

jpn
10th October 2006, 16:15
Try swapping these two lines (set the modified cursor first, then ensure it's visible):


editor->ensureCursorVisible();
editor->setTextCursor(text_cursor);

Ti_Thom
10th October 2006, 16:37
Well, it does not work. The line is still highlighted but only the begining of the file is visible :(

jpn
10th October 2006, 17:18
Ok, I see the problem. QWidget's geometry is calculated upon first show event. You should move the ensureCursorVisible() call in QTextEdit's showEvent() or into a slot connected to a single shot timer with timeout 0. This ensures that the geometry is constructed properly before trying to do operations which rely on widget's geometry.

Either subclass QTextEdit and override it's showEvent():


void MyTextEdit::showEvent(QShowEvent* event)
{
QTextEdit::showEvent(event);

static bool initialized = false;
if (!initialized)
{
ensureCursorVisible();
initialized = true;
}
}


Or use the timer technique:


// add this in place where you had "editor->ensureCursorVisible();"
QTimer::singleShot(0, this, SLOT(initialize()));

// declared as a slot
void BodyWidget::initialize()
{
// QTextEdit* editor moved as a member variable
editor->ensureCursorVisible();
}
editor->ensureCursorVisible();

Ti_Thom
10th October 2006, 17:33
I was also thinking about the widget's geometry computation and tryed to put "editor->ensureCursorVisible();" at the end of the BodyWidget build function, the visible text was not the right part.

I just tryed your 2nd technique, it seems to work as expected. Thanks ! :)

dahiya.himanshu
27th September 2012, 06:04
QTextCursor* highlightCursor;
QTextEdit *ui_textEdit;
...
ui_textEdit->setTextCursor(*highlightCursor);
ui_textEdit->ensureCursorVisible();

just make sure u set the cursor using setTextCursor instead of ui_textEdit->textCursor().setPosition() and u call ensureCursorVisible after that.

Himanshu Dahiya