Home > Enterprise >  Qt How to stop shift-tab from changing widget focus?
Qt How to stop shift-tab from changing widget focus?

Time:08-26

I'm trying to set up a text edit that does the shift tab remove indentation thing that code editors do; but i can't respond to shift tab because it changes the widget focus.

I tried overriding the event function in the main window and that didn't work; then i tried event filters on all widgets and that didn't work; then i tried overriding QApplication::notify like so:

class MyApplication : public QApplication
{
    Q_OBJECT
public:
    MyApplication(int argc, char *argv[]) : QApplication(argc, argv) { }
    virtual ~MyApplication() = default;

    bool    notify(QObject * o, QEvent *e) override
    {
        if (e->type() == QEvent::KeyPress)
        {
            QKeyEvent* k = static_cast<QKeyEvent*>(e);

            if (k->key() == Qt::Key_Tab && dynamic_cast<QPlainTextEdit*>(focusWidget()))
            {
                // filter tab out
                return false;
            }
        }

        return QApplication::notify(o, e);
    }
};

And that didn't work; and additionally it crashes in QCoreApplication::arguments unless I run the application from inside valgrind for some reason.

Regardless I'm out of ideas, how can i stop shift tab from changing focus?

CodePudding user response:

If you are using QTextEdit or QPlainTextEdit, which is quite likely, you can set the Tab behavior using tabChangesFocus property. See https://doc.qt.io/qt-6/qtextedit.html#tabChangesFocus-prop and https://doc.qt.io/qt-6/qplaintextedit.html#tabChangesFocus-prop

CodePudding user response:

I was able to implement the desired behavior in Qt's included qtbase/examples/widgets/widgets/lineedits example program, by inserting the following code into main.cpp, just above int main(int, char **):

class BackTabFilter : public QObject
{
public:
   BackTabFilter(QObject * parent) : QObject(parent)
   {
      qApp->installEventFilter(this);
   }

   virtual bool eventFilter(QObject * watched, QEvent * e)
   {
      if ((e->type() == QEvent::KeyPress)&&(static_cast<QKeyEvent *>(e)->key() == Qt::Key_Backtab))
      {
         QLineEdit * le = dynamic_cast<QLineEdit *>(qApp->focusWidget());
         if (le)
         {
            le->setText(le->text()   " Bork!");
            return true;  // eat this event
         }
      }
      return QObject::eventFilter(watched, e);
   }
};

.... and then adding this line into main() itself (just below the QApplication app(argc,argv); line):

BackTabFilter btf(NULL);

With these changes, pressing shift-Tab while the focus is on one of the QLineEdits in the GUI causes the word "Bork!" to be appended to the QLineEdit's text, rather than having the widget-focus change.

  •  Tags:  
  • c qt
  • Related