[Qt-interest] Autoscrolling--yet friendly--QTextEdit

Sherif Ghali sherif.ghali at yahoo.com
Tue Dec 14 04:45:33 CET 2010


Thank you, Josh and Bill, for the hints.
 
Taking a clue from the implementation of:
    void QTextEditPrivate::_q_ensureVisible(const QRectF &_rect)
in 
    qt-everywhere-opensource-src-4.7.1/src/gui/widgets/qtextedit.cpp
here is one solution.

#include <QtGui>
 
class MyQTextEdit : public QTextEdit
{
public:
    MyQTextEdit(QWidget * parent = 0)
        : QTextEdit(parent),
          n(0)
    {}
 
protected:
    virtual void timerEvent(QTimerEvent * /*event*/)
    {
        insertHtml(QString("Message: <b>%1</b>").arg(n++));
        insertPlainText(QString("\n"));
 
        if(end_is_visible())
            keep_end_visible();
    }
 
    bool end_is_visible() const
    {
        QScrollBar * vbar = verticalScrollBar();
        return (vbar->maximum() - vbar->value()) < vbar->singleStep();
    }
 
    void keep_end_visible()
    {
        QTextCursor c = this->textCursor();
        c.movePosition(QTextCursor::End);
        this->setTextCursor(c);
    }
 
    int n;
};
 
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
 
    MyQTextEdit * myqtextedit = new MyQTextEdit;
    myqtextedit->resize(300,80);
 
    QBasicTimer timer;
    timer.start(1000, myqtextedit);
 
    myqtextedit->show();
    return app.exec();
}

This code is almost right. The new end after insertion is kept
visible if the end was already visible. But there are two issues:

--This is the case on Windows XP but not on OS X 10.6 (Snow Leopard).
  The version of Qt on both OSes is 4.7.0.

--Because we have to use QTextEdit::insertX rather than
  QTextEdit::append, clicking somewhere in the middle of the log
  causes new insertions to go there. Let's call it a feature.

Sherif



      



More information about the Qt-interest-old mailing list