Bienvenue sur le forum !

Si vous souhaitez rejoindre la communauté, cliquez sur l'un de ces boutons !

Qt : 5.12.0 - Qt Creator : 4.8.0 - Qt Installer : 3.0.6 - JOM : 1.1.2 - QBS : 1.12.2

Positionner le mot recherché au milieu de la scrollArea du QTextEdit

Bonsoir,
Je cherche le moyen rationnel pour positionner la scrollBar d'un QTextEdit affichant un texte, de telle sorte que le mot recherché (si trouvé) se trouve affiché approximativement au centre du QTextEdit.

Actuellement, je m'en tire avec le code suivant (où le mot recherché appartient au paragraphe 6 sur un total de 2 paragraphes, valeurs déterminées visuellement pour tester la méthode):
void MainWindow::find()
{
QString searchString(ui->lText->text());//mot à rechercher dans le texte affiché
if (!searchString.isEmpty())
{
QTextDocument *document = ui->tText->document();
bool found = false;

if (isFirstTime == false)
document->undo();

QTextCursor highlightCursor(document);
QTextCursor cursor(document);

/*QTextCursor curs(ui->tText->textCursor());
curs.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
ui->tText->setTextCursor(curs);*/

cursor.beginEditBlock();
QTextCharFormat plainFormat(highlightCursor.charFormat());
QTextCharFormat colorFormat = plainFormat;
colorFormat.setForeground(Qt::red);

while (!highlightCursor.isNull() && !highlightCursor.atEnd()) {
highlightCursor = document->find(searchString, highlightCursor, QTextDocument::FindWholeWords);

if (!highlightCursor.isNull()) {
found = true;
highlightCursor.movePosition(QTextCursor::WordRight,
QTextCursor::KeepAnchor);
highlightCursor.mergeCharFormat(colorFormat);

highlightCursor.movePosition(QTextCursor::StartOfWord,
QTextCursor::MoveAnchor);//StartOfWord
ui->tText->setTextCursor(highlightCursor);
}
}
cursor.endEditBlock();
isFirstTime = false;

int min = ui->tText->verticalScrollBar()->minimum();
int max = ui->tText->verticalScrollBar()->maximum();

status(QString("scroll: %1,%2").arg(min).arg(max));

//mot recherché appartient au paragraphe 6 sur un total de 20 paragraphes
int value = 6*(max - min)/20;
ui->tText->verticalScrollBar()->setValue(value);//ajuste la scrollBar pour avoir le mot trouvé au centre
}
}
NB: Le texte est lu dans un fichier texte et affiché dans le QTextEdit:

QFile fichier(fName);

if (fichier.open(QIODevice::Text | QIODevice::ReadOnly))
{
ui->tText->clear();
QTextStream in(&fichier);
in.setCodec(QByteArray("UTF-8"));//html codé en utf-8
QString s = in.readAll();//texte encodé
fichier.close();
ui->tText->append(s);

QTextCursor curs(ui->tText->textCursor());
curs.movePosition(QTextCursor::Start,QTextCursor::MoveAnchor);
ui->tText->setTextCursor(curs);
}
cf. à l'écran: voir capture

Une piste pour rationnaliser la méthode?
jpg
jpg
C-000825.jpg
25K

Réponses

  • Salut,

    Tu peux utiliser:
    QTextEdit::ensureCursorVisible()
    ou
    QRect QTextEdit::cursorRect(const QTextCursor &cursor) const
    et utiliser:
    QScrollArea::ensureVisible(int x, int y, int xmargin = 50, int ymargin = 50)
  • @mpergand: salut,
    j'ai ajouté le code suivant au sortir de la boucle

    while()//recherche du mot
    {}
    //ajout
    ui->tText->ensureCursorVisible();
    QRect cRect(ui->tText->cursorRect());
    QScrollArea *scrollArea = new QScrollArea(ui->tText->viewport());
    scrollArea->ensureVisible(cRect.x(),cRect.y(),50);
    Mais je n'ai pas le résultat escompté cf. capture
    En fait sans ajout du code, j'ai la même disposition (en bas de la zone du QTextEdit)
    Ou je n'ai pas bien interprété ta proposition à propos de QScrollArea...
    jpg
    jpg
    C-000826.jpg
    27K
  • C'est le bazar !
    QScrollBar *vbar = textEdit->verticalScrollBar();
    int y = textEdit->cursorRect().top()+vbar->value(); // pos dans le document
    int pos=y-vbar->pageStep()/2; // on remonte d'une demi page

    if(pos>vbar->minimum() && pos<vbar->maximum())
    vbar->setValue(pos);
    Le bazar, c'est que cursorRect est une position relative à la position du scrollBar.
    Très bizarre ...
  • @mpergand: ah ah!
    Et pourtant ça a tout l'air d'un truc simple... mais comme souvent en pareil cas, la solution n'est pas immédiate. Bon, je continue à regarder. Wait & see.
Connectez-vous ou Inscrivez-vous pour répondre.