PDA

View Full Version : QGraphicsTextItem focus problem



Gopala Krishna
25th June 2007, 19:54
I've been playing with QGraphicsTextItem to display editable property texts of the components(QGraphicsItems). I found this (http://www.qtcentre.org/forum/f-qt-programming-2/t-qgraphicstextitem-is-it-a-bug-there-4065.html) helpful.
But unfortunately now the shortcut assigned to one of QAction interferes while editing text in textitem.
That QAction is assigned to delete key whose job is to delete selected components.
Because of this delete key doesn't work in the edit which triggers the action instead.
ShortcutContexts were helpless here. I can't even use grabKeyboard() since it is not a widget. :eek:

Please do help me solve this problem.

jpn
26th June 2007, 10:26
How about enabling/disabling the action on the fly, more or less like this:


class MyTextItem : public QGraphicsTextItem // QGraphicsTextItem inherits QObject
{
Q_OBJECT
...

signals:
void editing(bool);

protected:
void focusInEvent(QFocusEvent* event) {
QGraphicsTextItem::focusInEvent(event);
emit editing(true);
}

void focusOutEvent(QFocusEvent* event) {
QGraphicsTextItem::focusOutEvent(event);
emit editing(false);
}
};

connect(textItem, SIGNAL(editing(bool)), deleteAction, SLOT(setDisabled(bool)));

Gopala Krishna
26th June 2007, 10:54
How about enabling/disabling the action on the fly, more or less like this:


Thanks. It should work but there are many more keybindings that interferes, QKeySequence::Undo,QKeySequence::Redo.... I just made a note of them from source of QTextControl. Probably i need to add all action that interferes in a list and enable/disable them appropriately. But what if these shortcuts vary with qt versions - ? I mean if the next version adds/removes a shortcut. Oh! :crying:

I really tried hard by going through the souce code of QShortCutMap, QTextControl,QAction,QApplication .. but still there seems to be no clean hack to do this. QGraphicsView::grabKeyboard() doesn't help either since its child of mainwindow :( Are there any other tricks - possibly eventFilter , actionEvent ..

I am using Qt-4.2.3 on x11.

Gopala Krishna
26th June 2007, 17:08
I just made a note of them from source of QTextControl. Probably i need to add all action that interferes in a list and enable/disable them appropriately. But what if these shortcuts vary with qt versions - ? I mean if the next version adds/removes a shortcut.

For now I had to stick on to this solution. I worte the followingg code based on suggestion of jpn.

void QucsMainWindow::setInterferingActionsDisabled(bool state)
{
foreach(QAction *action, interferingActions) {
action->setDisabled(state);
#if QT_VERSION < 0x040300
Qt::ShortcutContext c = state ? Qt::WidgetShortcut : Qt::WindowShortcut;
action->setShortcutContext(c);
#endif
}
}


Yup you do need that preprocessor directive since qt-4.2.* has a bug where the action, though disabled, responds to the shortcuts associated. But it seems to be fixed in qt4.3

BTW, is modifying shortcut context a heavy operation since i may be ececuting this slot quite often ?

I still will be happy to modify my code if someone can help me with more cleaner hack :)

jpn
26th June 2007, 17:16
Another way could be to install an event filter on the application object:


class MyTextItem : public QGraphicsTextItem // QGraphicsTextItem inherits QObject
{
Q_OBJECT
...

public:
bool eventFilter(QObject* object, QEvent* event)
{
if (event->type() == QEvent::Shortcut ||
event->type() == QEvent::ShortcutOverride)
{
if (!object->inherits("QGraphicsView"))
{
event->accept();
return true;
}
}
return false;
}

protected:
void focusInEvent(QFocusEvent* event) {
QGraphicsTextItem::focusInEvent(event);
qApp->installEventFilter(this);
}

void focusOutEvent(QFocusEvent* event) {
QGraphicsTextItem::focusOutEvent(event);
qApp->removeEventFilter(this);
}
};

Gopala Krishna
26th June 2007, 18:25
Another way could be to install an event filter on the application object:


class MyTextItem : public QGraphicsTextItem // QGraphicsTextItem inherits QObject
{
Q_OBJECT
...

public:
bool eventFilter(QObject* object, QEvent* event)
{
if (event->type() == QEvent::Shortcut ||
event->type() == QEvent::ShortcutOverride)
{
if (!object->inherits("QGraphicsView"))
{
event->accept();
return true;
}
}
return false;
}

protected:
void focusInEvent(QFocusEvent* event) {
QGraphicsTextItem::focusInEvent(event);
qApp->installEventFilter(this);
}

void focusOutEvent(QFocusEvent* event) {
QGraphicsTextItem::focusOutEvent(event);
qApp->removeEventFilter(this);
}
};


Hey that works like a charm. Thanks a lot! :)