I am writing a keyboard tester, so I start a dialog with
keybDialog keyboardTestWindow;
keyboardTestWindow.setWindowTitle("Keyboard test");
keyboardTestWindow.exec();
override the keyPressEvent(QKeyEvent *event) and the test works superb. Now, I needed use of some parameters from parent, so instead I did
keybDialog keyboardTestWindow(m_parent);
keyboardTestWindow.setWindowTitle("Keyboard test");
keyboardTestWindow.exec();
and implemented what I needed. Now I discovered that just by instantiating the class and passing the parent to it, my dialog no longer receives the keyPressEvent. Are these passed to m_parent in some way? How can I avoid this?
EDIT:
The beginning of my keyPressEvent:
void keybDialog::keyPressEvent(QKeyEvent *event)
{
ui->txtBxKeyboardInput->clear();
qDebug() << "Event: " << hex << event->key() << event->nativeVirtualKey() << event->modifiers() << event->nativeModifiers() << event->nativeScanCode();
ui->txtBxKeyboardInput->setText(ui->txtBxKeyboardInput->text()+event->text());
switch(sequenceNumber)
{
case 0: // Left Shift + R
if( (event->key() == Qt::Key_R) && event->modifiers() == Qt::ShiftModifier && event->nativeModifiers() == 0x201)
{
reportSuccessfullKey(sequenceNumber);
}
else
{
ui->lblStatus->setText("WRONG");
}
break;
Related
I expect my program to print "mouse on label name" when my mouse is located on the labelname (a QLabel), and to print"mouse not on label name" when my mouse is not located on the labelname.
Even though I put my mouse on labelname, my program prints "mouse not on label name".
How can I know when my mouse is not on the labelname?
bool Dialog::eventFilter(QObject *obj, QEvent *e)
{
if(qobject_cast<QLabel*>(obj) == ui->labelname) {
cout << “mouse on label name” << endl;
}else if(qobject_cast<QLabel*>(obj) != ui->labelname) {
cout << “mouse not on label name” << endl;
}
return false;
}
Be sure you are installing the event filter correctly. Also, if you want to track mouse position you have to enable mouseTracking, otherwise the move events won't be triggered (though QEvent::Enter and QEvent::Leave will, which are the ones that indicates the mouse has entered or left the widget).
Here a minimal example of how to do it:
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
m_label = new QLabel("Hello world!");
m_label->setObjectName("m_label");
m_label->installEventFilter(this);
m_label->setMouseTracking(true);
auto hlayout = new QVBoxLayout();
hlayout->addWidget(m_label);
setLayout(hlayout);
}
bool MyWidget::eventFilter(QObject* sender, QEvent* event)
{
if (sender == m_label) {
qDebug() << sender->objectName() << event->type();
if (event->type() == QEvent::Enter) {
qDebug() << "mouse on label name";
} else if (event->type() == QEvent::Leave) {
qDebug() << "mouse not on label name";
}
}
return QWidget::eventFilter(sender, event);
}
The full working example is available in GitHub.
Pretty much as the tittle says, when i drag an item from QTableWidget it adds a child to ui->table->children, and then it launches ChildAdded event to my eventFilter, the problem is that if i drop the dragged item into an area that doesn't accept dropping that child won't be removed from ui->table->children whereas releasing the dragged item within an area that has dropping enabled it will, and also launches ChildRemoved event.
Here is my init code:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
m_ui(new Ui::MainWindow)
{
m_ui->setupUi(this);
m_ui->left_table->installEventFilter(this);
m_ui->right_table->installEventFilter(this);
m_ui->left_table->setColumnCount(1);
m_ui->left_table->setRowCount(25);
m_ui->left_table->setHorizontalHeaderLabels({"Source"});
m_ui->left_table->horizontalHeader()->setStretchLastSection(true);
m_ui->left_table->setAcceptDrops(false);
m_ui->left_table->setDragEnabled(true);
m_ui->right_table->setColumnCount(1);
m_ui->right_table->setHorizontalHeaderLabels({"Receiver"});
m_ui->right_table->horizontalHeader()->setStretchLastSection(true);
m_ui->right_table->setAcceptDrops(true);
for (int i = 0; i < 25; ++i) {
m_ui->left_table->setItem(i, 0, new QTableWidgetItem(QString::number(i)));
}
qDebug() << "Left childs: " << m_ui->left_table->children().size();
}
and the event filter:
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::ChildAdded || event->type() == QEvent::ChildRemoved) {
qDebug() << "Object: " << watched->objectName()
<< " Event: " << event->type()
<< "Childs: " << m_ui->left_table->children().size();
}
return false;
}
Example of dropping on invalid area, this wont remove the child added before:
Example of dropping on valid area, this will remove the child and call the ChildRemoved event:
I am making console style game in sfml. It's graphical interface but game itself contains console. I'm using Text Entered event for writing things in console but i also want to move the cursor (console cursor not mouse) with arrow keys. To be more specific in text entered event i am using event.text.unicode for key value. But arrow keys unicode values not working in my pc. I used 37 for left arrow, 39 for right arrow but it doesn't work. This is my console's key process function.
void Console::update(int unicode) {
if(unicode == 8) { // Backspace
deleteLast();
} else if(unicode == 13) { // Enter
newLine();
} else if(unicode == 37) { // Left arrow key
currentX--;
std::cout << "Left arrow" << std::endl;
} else if(unicode == 39) { // Right arrow key
currentX++;
std::cout << "Right arrow" << std::endl;
} else { // Normal characters
buffer[(currentY == 0) ? currentX : (currentY * maxColumn) + currentX] = (char)unicode;
currentX++;
if(currentX == maxColumn - 1) {
newLine();
}
std::cout << "[KEY TYPED] X: " << currentX << " Y: " << currentY << std::endl;
}
}
Thanks in advance :)
Edit: I think i solved. I used KeyPressed event for handling special keys. And TextEntered for handling normal characters.
For those having the same problem:
From an Event type variable, first check if its a keyboard event
if(event.type == sf::Event::KeyPressed)
Then check if its an arrow:
if(event.key.code == sf::Keyboard::Up)
//do stuff
if(event.key.code == sf::Keyboard::Down)
//do stuff
I have a custom button that can be right clicked in addition to left clicking. It works like this:
private slots:
void mousePressEvent(QMouseEvent *e) {
if(e->button() == Qt::RightButton) {
std::cout << "kek2";
emit rightClicked();
}
QPushButton::mousePressEvent(e);
}
For some weird reason left click works fine, and right clicks are not processed (judging by lack of kek2 outputs) until I do a left click, upon which all right clicks are processed at once. Why?
I had a look at it and implemented an equivalent Button and changed your code to this:
void QRightClickButton::mousePressEvent(QMouseEvent *e)
{
if(e->button() == Qt::RightButton) {
std::cout << "kek2" << std::endl; //the << std::endl; //made it work good again
emit rightClicked();
} else if(e->button() == Qt::LeftButton) {
//this else if block is just a fast implementation of the leftclick
std::cout << "kek3" << std::endl;
QPushButton::mousePressEvent(e);
}
}
Try it yourself both log messages ("kek2" as well as "kek3") appear instantly.
Without the << std::endl; it is still buggy!
EDIT: I decided to add 2 more ways to do it!
You can also use it without std::endl;
std::cout << message; //prints message
std::cout.flush(); //flushes the output so it will be visible as well
For example you can create your own class or your own function.
Use qDebug(). qDebug automatically flushes the stream so you don't have to write extra code as well as it belongs to Qt self. That means you're not going to mix 2 libraries.
Use it that way:
qDebug() << message;
You should use qDebug() since it ensures that the output is immediately flushed. std::cout doesn't have to. E.g. qDebug() << "kek2". When using Qt, don't use std::cout for debug output, it's not worth it.
mousePressEvent is not a slot.
I was wondering if there was a way I could remove all keyboard shortcuts from the UI so I can use the event filter to grab key commands instead.
Currently, I have this in my eventFilter() function and it does the job but it also affects the QSliders, QLineEdits and QButtons I have on there - and I don't want it to.
bool LinkControl::eventFilter(QObject *o, QEvent *e)
{
QKeyEvent *keyEvent = NULL;
// qDebug() << "TYPE: " << e->type();
switch(e->type())
{
case 51:
// qDebug() << this->overrideControl;
if(this->overrideControl == true)
{
keyEvent = static_cast<QKeyEvent*>(e);
// this->handleKeyboardInput(true, keyEvent->key());
// emit handleInput(true, keyEvent->key());
this->handleKeyboardInput(true, keyEvent->key());
// qDebug() << "PRESS: " << keyEvent->key();
}
this->overrideControl = !this->overrideControl;
return true;
break;
case QEvent::KeyRelease:
keyEvent = static_cast<QKeyEvent*>(e);
// this->handleKeyboardInput(false, keyEvent->key());
// emit handleInput(false, keyEvent->key());
this->handleKeyboardInput(false, keyEvent->key());
// qDebug() << "RELEASE: " << keyEvent->key();
return true;
break;
default:
return QMainWindow::eventFilter(o, e);
}
}
For example, In my handleKeyboardInput function, I have the up arrow key increment a value and it does that but it also moves a QSlider if it's selected.
Thank you.