PDA

View Full Version : How can I replace every keypress character with my custom key in lineedit?



binary001
31st October 2015, 17:39
Hi,

I've my custom key maps table (A=c, B=f, C=d, ..... etc.)

I type and show the texts in lineedit normally,
but after checked a checkbox, I want to replace every letter immediately with my custom map letter.

eg. in unchecked mode I type ABCDE then I checked and keep type ABCDE, the letters in lineedit is as follow:
ABCDcfdj
I want to see and replace letter in lineedit's every key pressed.

In VB, this work is very easy. In Qt C++, how can I do it?

my sample vb code are:

Private Sub Text1_KeyPress(KeyAscii As Integer)
If ckMyMap.Value = 1 Then KeyAscii = KeyMap(KeyAscii)
End Sub

Public Function KeyMap(key As Integer) As Integer
'My Custom Key Map
If key = 65 Then
KeyMap = 99
ElseIf key = 66 Then
KeyMap = 102
ElseIf key = 67 Then
KeyMap = 100
ElseIf key = 68 Then
KeyMap = 106
ElseIf key ......
...............
...............
Else
KeyMap = key
End If
End Function

In Qt C++, how can I do it?

Thanks.

ChrisW67
31st October 2015, 20:00
Subclass QLineEdit and override eventFilter() something like this:


bool TranslatingEdit::eventFilter( QObject * watched, QEvent * event )
{
TranslatingEdit *edit = qobject_cast<TranslatingEdit *>(watched);
if ( edit && event->type() == QEvent::KeyPress ) {
QKeyEvent *k = static_cast<QKeyEvent *>( event );
// your mapping logic here this is an example for a single key
if ( k->key() == Qt::Key_Space) {
QEvent *evtSpace = new QKeyEvent(QEvent::KeyPress, Qt::Key_Underscore, Qt::NoModifier, "_");
qApp->postEvent(edit, evtSpace );
return true; // this stops the original event here
}
}
return QLineEdit::event(event);
}

Then install this filter on the widget itself in its constructor:


installEventFilter(this);


The filter code can be in any QObject , for example a parent form class, if that is more convenient.

Edit: Actually, in hindsight, this might lead to an infinite loop if you map a key to another key that is also subject to mapping.

ChrisW67
1st November 2015, 06:34
You could try this (untested code):


// a new member variable (init to false in constructor)
bool m_translating;

// A getter
bool TranslatingEdit::isTranslating() const { return m_translating; }

// a setter/slot you can connect from your checkbox clicked(bool) signal
void TranslatingEdit::setTranslating(bool flag) { m_translating = flag; }

// and a protected override
void TranslatingEdit::keyPressEvent( QKeyEvent * event )
{
if (m_translating) {
// your mapping logic here this is an example for a single key
if ( event->key() == Qt::Key_Space) {
QKeyEvent newEvent(QEvent::KeyPress, Qt::Key_Underscore, Qt::NoModifier, "_");
QLineEdit::keyPressEvent(&newEvent);
event->setAccepted(newEvent.isAccepted());
}
}
else {
return QLineEdit::keyPressEvent(newEvent);
}
}

binary001
2nd November 2015, 17:19
Thanks,

It's working!

ChrisW67
2nd November 2015, 19:39
The second option? Actually, I can see that in Line 22 in my second post does not need the "return" (possible compiler warning) and should call the base implementation with "event" not "newEvent" (would not compile).