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 :
#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 ?
I'm not sure, but your eventFilter
is strange. It conflicts with mouse processing of QLineEdit.
return QLineEdit::eventFilter();
in default section.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.