PDA

View Full Version : Stop keyboar-scrolling of QGraphicsView / Filter KeyPressEvents



0backbone0
27th August 2015, 23:47
The Node Editor I am currently working on is coming along nicely.

11341

However there is a hopefully small issue with the QGraphicsView behaving to Cursor Key Presses.
Right now the Scene is catching the Keyboard Events.
For example the Cursor Keys Move all selected Nodes around.
Scrolling is realised with Scroll Hand Drag. However , by default, the Cursor Keys move the Scroll bars around to.

I tried to shut them out like this:


void nodegraphicsview::keyPressEvent(QKeyEvent *event)
{
if(event->key()==Qt::Key_Up || event->key()==Qt::Key_Down || event->key()==Qt::Key_Left || event->key()==Qt::Key_Right)
{
//do nothing
}
else
{
QGraphicsView::keyPressEvent(event);
}
}

Witch works, but now I also have a QLineEdit Widget in my Scene that shows up on top of a Node after DoubleClicking the Title to Rename it.
The Cursor keys are then Blocked for the Line Edit as well.
Can I forward the events directly to the LineEdit somehow?
Any other Ideas how solve this?

anda_skoa
28th August 2015, 07:38
You could try with an event filter and examining the recipient object.
If it is the line edit allow the event to pass, if it is the view, don't.
Maybe need to check the application's focusWidget if the recipient parameter of the event filter doesn't work.

Cheers,
_

0backbone0
28th August 2015, 14:19
This is way harder than I expected!
I did a combination of Eventfilter and Focuschecking.

The Slot looks like this (where renameproxy is the QGraphicsProxyWidget of the LineEdit):


void MainWindow::checkfocus(QGraphicsItem *newFocusItem, QGraphicsItem *oldFocusItem, Qt::FocusReason reason)
{
if (newFocusItem==renameproxy)
{
ui->graphicsView->removeEventFilter(filter);
}
else
{
ui->graphicsView->installEventFilter(filter);
}
}


and is connected to the Scene like so:


connect(scene,SIGNAL(focusItemChanged(QGraphicsIte m*,QGraphicsItem*,Qt::FocusReason)),this,SLOT(chec kfocus(QGraphicsItem *, QGraphicsItem *, Qt::FocusReason)));


It would work to if I just had the LineEdit Widget. However now I cant move the selected Nodes around any more.
After around 3 h of experimenting and testing it's starting to get me frustrated.
One Possible solution I found would be to reimplement scrollContentsBy() of the GraphicsView. but this also means that I would have to handle draging the Scene around myself.
From all that experimenting my Code looks quite messy right now. After fixing this, and a break I probably will try to implement the dragscoll and post the result.

0backbone0
28th August 2015, 16:42
I finally did it without messing with scrollContentsBy().
After Subclassing QLineEdit I could simply filter out outgoing Up and Down Keypresses.(Left and Right are handled by QLineEdit anyway)



void customLineEdit::keyPressEvent(QKeyEvent *event)
{

if (event->key()!=Qt::Key_Up && event->key()!=Qt::Key_Down)
{
QLineEdit::keyPressEvent(event);
}
}


The FocusCheck part had to be modified slightly to:



void MainWindow::checkfocus(QGraphicsItem *newFocusItem, QGraphicsItem *oldFocusItem, Qt::FocusReason reason)
{
if (newFocusItem==renameproxy)
{
emit deselectall();
}
else
{
renameproxy->hide();
}

if (newFocusItem!=NULL)
{
scene->removeEventFilter(filter);
}
else
{
scene->installEventFilter(filter);
}
}


In addition I had to deselect all Nodes in my Scene to avoid moving them around while navigating inside the LineEdit.
It is still not perfect, but I am getting there....

@Admin:
I want to set the Thread to solved but the Edit button in the first post vanished. How do I do that?
Why is there no Button or Checkbox to do this?