QKeyPress - Simulating key press in Qt - c++

How can I simulate user interaction (key press event) in Qt?
I tried the same approach, but not able to get written on the lineEdit widget
ui->lineEdit->setFocus();
QKeyEvent *key_press = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_X, Qt::NoModifier);
QApplication::sendEvent(ui->lineEdit, key_press);
Alternately
QApplication::postEvent(ui->lineEdit, key_press);
also didn't succeed.
I tried the below also and didn't get any result.
QKeyEvent key(QEvent::KeyPress, Qt::Key_X, Qt::NoModifier);
QApplication::sendEvent(ui->lineEdit, &key);
if (key.isAccepted()) {
qDebug()<<"everything is ok";
} else {
qDebug()<<"something wrong";
}
Please suggest what am I missing.
Regards,
Sayan

In the link you indicate an enter is given so the text is not necessary, but in the case you want to send a letter you must pass that parameter:
ui->lineEdit->setFocus();
QKeyEvent *key_press = new QKeyEvent(QKeyEvent::KeyPress, Qt::Key_X, Qt::NoModifier, "X");
// text ─────┘
QApplication::sendEvent(ui->lineEdit, key_press);

Related

QT: Ignore key events on checkbox selection

I have a QT Application on Windows which has a mode of using arrow keys, and also a mode which should totally ignore these arrow keys. That is, I want the arrow keys to not to trigger any event once the user checks a box.
I saw a post where eventFilter() was suggested, but I did not get how I could use it. Here is the checkbox event that listens the user, and gets triggered once the user checks it. In the else part I want the eventFilter() to work for arrow keys, but so far I could not get it running.
void MainWindow::on_checkBoxSmartCutMode_stateChanged(int arg1)
{
if (arg1 == 0)
{
// do as usual, arrow keys should work
}
else
{
eventFilter(); // if any arrow key is pressed, ignore the event
}
}
Any suggestions?
You can use keyEvent as your key filter by override keyPressEvent and test your checkbox state.
example:
void MainWindow::keyPressEvent(QKeyEvent *event)
{
// check your checkbox state
if (ui->poCheckBox->checkState() == Qt::Unchecked)
// do as usual, arrow keys should work
return;
switch(event->key())
{
case Qt::Key_Left:
case Qt::Key_Right: // add more cases as needed
event->ignore(); // if any arrow key is pressed, ignore the event
return;
}
// handle the event
}

Qt - Implementing QKeyEvent

How do I implement keyboard listening in Qt? I have the following setup that's not working. I have two classes, gameLogic and gameView. gameView has an instance of gameLogic:
gameView::gameView(QWidget *parent)
: QWidget(parent)
{
logic = new gameLogic(6);
logic->setFocusPolicy(Qt::TabFocus); //in one of the articles I read, this was supposed to fix the issue. It doesn't for me.
this->resize(1200, 700);
this->setStyleSheet("background-color: white");
QString str;
str.setNum(logic->n);
connect(logic, SIGNAL(playerStepped(int, int)), this, SLOT(movePlayer(int, int)));
}
And in gameLogic I am handling the keystrokes as follows:
void gameLogic::keybrdStep( QKeyEvent * keypressed )
{
if (keypressed->key() == Qt::Key_Q) {
_message = new QMessageBox;
_message->setText("Q");
_message->exec();
}
}
No matter how many times I push the button Q, nothing happens. What am I doing wrong? Which part am I missing? I'm on Linux Mint with the latest version of Qt.
void gameLogic::keybrdStep( QKeyEvent * keypressed )
Where did you get the method name "keybrdStep" from? Who do you think should call it?
The name of the method you need to override to get key presses is QWidget::keyPressEvent()

QTextEdit - How to "cancel" entered key codes in onKeyPress()

I am trying to "cancel" key codes in QTextEdit or QPlainTextEdit. When I say cancel, what I mean is, I want to turn the "entered" character into "nothing" depending on the key entered. Example: if the user hits "a" or "b" on the keyboard, I would not want to have "a" or "b" displayed / entered into the text, instead, the input would be ignored and turned into nothing / won't be processed.
With C++ Builder, you have a KeyDown_Event and a "Key" parameter. Once you detect the entered key code, if you don't like it, you can set the "Key" parameter to 0, so you set "Key = 0" and the key stroke would not be displayed. How do I achieve the same thing in Qt?
Let me explain with code:
if (e->key() == 67)
// do not send "c" to the QTextEdit (In C++ Bullder, you would do Key = 0)
if (e->key() == 65)
// do not send "a" to the QTextEdit (In C++ Bullder, you would do Key = 0)
How do I do this in Qt?
I tired doing e->setAccepted(false) and e->Ignore() but it made no difference. I think by the time e->ignore() is executed, the "char" is already inserted into the text box. With C++ Builder, you can intercept this with the KeyDown event and cancel it. I can't seem to find a way with Qt.
Thx
Similar to void QObject::installEventFilter ( QObject * filterObj ) example:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
setupUi(this);
textEdit->installEventFilter(this);
}
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if (watched == textEdit && event->type() == QEvent::KeyPress) {
QKeyEvent *e = static_cast < QKeyEvent * >(event);
if (e->key() == Qt::Key_A) {
return true;
}
}
return QMainWindow::eventFilter(watched, event);
}
UPDATE
As IInspectable noticed, this won't help you with filtering Ctrl+C/Ctrl+V method. If you need these either, you'll need to connect to QTextEdit::textChanged signal and updated the text manually. Something like this:
static QString oldString;
QString s = textEdit->toPlainText();
if (s == oldString)
return;
int pos = textEdit->textCursor().position();
s.remove('a', Qt::CaseInsensitive);
oldString = s;
textEdit.setPlainText(s);
QTextCursor cursor = textEdit->textCursor();
cursor.setPosition(pos);
textEdit->setTextCursor(cursor);

Catch ESC key press event when editing a QTreeWidgetItem

I'm developing a project in Qt. I have a QTreeWidget(filesTreeWidget) whith some file names and a button for creating a file. The Create button adds to the filesTreeWidget a new item(the item's text is "") who is edited for choosing a name. When I press ENTER, the filename is send through a socket to the server. The problem comes when I press ESC because the filename remains "" and is not send to the server. I tried to overwrite the keyPressEvent but is not working. Any ideas? I need to catch the ESC press event when I'm editing the item.
You can subclass QTreeWidget, and reimplement QTreeView::keyPressEvent like so:
void MyTreeWidget::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Escape)
{
// handle the key press, perhaps giving the item text a default value
event->accept();
}
else
{
QTreeView::keyPressEvent(event); // call the default implementation
}
}
There might be more elegant ways to achieve what you want, but this should be pretty easy. For example, if you really don't want to subclass, you can install an event filter, but I don't like doing that especially for "big" classes with lots of events because it's relatively expensive.
Implement keyPressEvent function as following:
void TestTreeWidget::keyPressEvent(QKeyEvent *event)
{
switch (event->key())
{
case Qt::Key_Escape:
{
escapeKeyPressEventHandler();
event->accept();
break;
}
default:
QTreeWidget::keyPressEvent(event);
}
}
TestTreeWidget::escapeKeyPressEventHandler()
{
// work with your QTreeWidgetItem here
}

QT Embedded: How to generate an event to ESC (Escape), F1 and such keys

I'm working on an embedded software in QT that uses LIRC to handle RC (Remote Control) key presses.
I managed to map all the RC keys so directFB is getting keypresses like these:
00000000000011b7 00 MENU
00000000000011a7 00 EXIT
0000000000001193 00 RED
I've created a QT class that uses sockets to grab LIRC keys and generate KeyPressEvents through QApplication::postEvent for all the other QT widgets and alike.
It works fine for "regular" keys, but it is not working for keys that emulate the ESC, F1, F2 and other "special" keys.
I could make it work using signals and slots (check it bellow), however, it's a harsh since I need to connect and disconnect the signals for active Windows (Widgets) all the time. I refuse to believe there is no better solution for that.
Does anyone know how to generate events for those special keys?
Following a code snippet of the LIRC socket handler method:
QKeyEvent *event = NULL;
int emitKey = 0;
if (strstr(code, "MENU"))
{
cout << "MENU";
event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Menu, Qt::NoModifier, "Menu", 0);
emitKey = Qt::Key_Menu;
}
else if (strstr(code, "EXIT"))
{
cout << "EXIT";
event = new QKeyEvent(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier, "Exit", 0);
emitKey = Qt::Key_Escape;
}
else if (strstr(code, "RED"))
{
cout << "RED";
event = new QKeyEvent(QEvent::KeyPress, Qt::Key_F1, Qt::NoModifier, "Red", 0);
emitKey = Qt::Key_F1;
}
// All other keys, including ...
if (event)
{
cout << ": POSTED!" << endl;
event->ignore();
QApplication::postEvent(this, event);
emit k_output(emitKey);
}
The Menu key event is reaching the active window's keyEvent method. The others (EXIT, RED) is not...
Thanks very much for your help.
The use of the current focused widget in the postEvent solves the problem.
I was having some issues in the LIRC configuration that was generating some "not that right" key codes.
If anyone need help on that, I'll be glad to help.
Thanks