Question

I created a custom QLineEdit for timecode (a timecode looks like this : hh:mm:ss:ff) edition.

It react with the keyboard and the mouse. If the user edit the timecode with the mouse (draging up/down a couple of digit) the highlighting is wrong : it select all the characters from the cursor to the end. (ie: If I drag mm the selection will be mm:ss:ff).

In order to get rid of that, I use setSelection(x,2) which select only the wanted digit (verified using qDebug() << selectedText()) but the highlighting is still wrong : enter image description here

#include "PhTimecodeEdit.h"

PhTimeCodeEdit::PhTimeCodeEdit(QWidget *parent) :
    QLineEdit(parent),
    _tcType(PhTimeCodeType25)
{
    connect(this, SIGNAL(textChanged(QString)), this, SLOT(onTextChanged(QString)));
    this->installEventFilter(this);
    _mousePressed = false;
    _selectedIndex = 0;
}

bool PhTimeCodeEdit::isTimeCode()
{
    PhFrame frame;
    QString text;
    frame = PhTimeCode::frameFromString(this->text(),_tcType);
    text = PhTimeCode::stringFromFrame(frame, _tcType);

    if(text == this->text())
        return true;
    else
        return false;
}
bool PhTimeCodeEdit::eventFilter(QObject *, QEvent *event)
{
    switch (event->type()) {
    case QEvent::MouseButtonPress:
        _mousePressed = true;
        _mousePressedLocation = static_cast<QMouseEvent *>(event)->pos();
        if(_mousePressedLocation.x() > 110 and _mousePressedLocation.x() < 145) {
            _selectedIndex = 0;
        }
        else if(_mousePressedLocation.x() > 145 and _mousePressedLocation.x() < 190) {
            _selectedIndex = 3;
        }
        else if(_mousePressedLocation.x() > 190 and _mousePressedLocation.x() < 230) {
            _selectedIndex = 6;
        }
        else if(_mousePressedLocation.x() > 230 and _mousePressedLocation.x() < 270) {
            _selectedIndex = 9;
        }
        return true;
    case QEvent::MouseButtonRelease:
        _mousePressed = false;
        return true;
    case QEvent::MouseMove:
        {
            if(_mousePressed) {
                int y = static_cast<QMouseEvent *>(event)->pos().y();
                PhFrame currentFrame = PhTimeCode::frameFromString(this->text(), _tcType);

                if(_selectedIndex == 0) {
                    if(_mousePressedLocation.y() > y)
                        currentFrame += 25 * 60 * 60;
                    else
                        currentFrame -= 25 * 60 * 60;
                }
                else if(_selectedIndex == 3) {
                    if(_mousePressedLocation.y() > y)
                        currentFrame += 25 * 60;
                    else
                        currentFrame -= 25 * 60;
                }
                else if(_selectedIndex == 6) {
                    if(_mousePressedLocation.y() > y)
                        currentFrame += 25;
                    else
                        currentFrame -= 25;
                }
                else if(_selectedIndex == 9) {
                    if(_mousePressedLocation.y() > y)
                        currentFrame++;
                    else
                        currentFrame--;
                }

                _mousePressedLocation.setY(y);
                this->setText(PhTimeCode::stringFromFrame(currentFrame, _tcType));
                            setSelection(_selectedIndex,2);
            }
            return false;
        }

    default:
        return false;
    }
}

What should I do to get it right ?

Was it helpful?

Solution

I'm not sure, but your eventFilter is strange. It conflicts with mouse processing of QLineEdit.

  1. Try to return QLineEdit::eventFilter(); in default section.
  2. You didn't implement mouse tracking. You should disable it with mouse capture and overloading mouse*Event();. Mouse events processing should be disabled while you track manually mouse.

Reason of bug: mouse moving, that processed by QLineEdit overrides text selection that you set in eventFilter. It happens on mouse release.

Possible hotfix (dirty): implement your own slot for set selection and call it via Qt::QueuedConnection. So your direct call of setSelection will be processed after releasing of mouse.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top