2

QDockWidget で単純な仮想キーボードを作成しています...
ウィジェットが QMainWindow にドッキングされると、選択されたウィジェット (qdoublespinbox など) が強調表示され、仮想キーボードをクリックすると clearFocus() が機能します...

QDockWidget がウィンドウの上に浮かんでいるときにボタンをクリックすると、clearFocus が機能せず、QMainWindow にフォーカスされたウィジェットが表示されません...

QDockWidget にフォーカスをまったく持たないようにするにはどうすればよいですか?

ありがとう :-)

これはコードです:

// class MyVirtualKeyboard : public QDockWidget

void MyVirtualKeyboard::sendKey(Qt::Key key, Qt::KeyboardModifier mod)
{
    this->clearFocus();

    QMainWindow *w = dynamic_cast<QMainWindow *>(this->parent());
    if(w == NULL) return;

    QWidget *widget = w->focusWidget();

    QString repr = QKeySequence(key).toString();

    QKeyEvent *pressEvent = new QKeyEvent(QEvent::KeyPress, key, mod, repr);
    QKeyEvent *releaseEvent = new QKeyEvent(QEvent::KeyRelease, key, mod, repr);

    qDebug("%s", pressEvent->text().toAscii().data());

    MyApplication *app = MyApplication::myInstance();

    app->postEvent(widget, pressEvent);
    app->postEvent(widget, releaseEvent);
}

void MyVirtualKeyboard::on_BTN_1_clicked()
{
    sendKey(Qt::Key_1);
}

...
4

4 に答える 4

2

呼び出しはclearFocus()不要なはずです。Dock ウィジェットとそのすべてのウィジェットにQt::NoFocusポリシーが必要です。

以下のコードは、その方法を示しています。

スクリーンショット

// https://github.com/KubaO/stackoverflown/tree/master/questions/vkb-focus-18558664
#include <QtGui>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtWidgets>
#endif

class Keyboard : public QDockWidget {
   Q_OBJECT
   QWidget m_widget;
   QGridLayout m_layout{&m_widget};
   QToolButton m_buttons[10];
   void sendKey(Qt::Key key, Qt::KeyboardModifier mod)
   {
      if (! parentWidget()) return;
      auto target = parentWidget()->focusWidget();
      if (! target) return;

      auto repr = QKeySequence(key).toString();
      auto pressEvent = new QKeyEvent(QEvent::KeyPress, key, mod, repr);
      auto releaseEvent = new QKeyEvent(QEvent::KeyRelease, key, mod, repr);
      qApp->postEvent(target, pressEvent);
      qApp->postEvent(target, releaseEvent);
      qDebug() << repr;
   }
   Q_SLOT void clicked() {
      auto key = sender()->property("key");
      if (key.isValid()) sendKey((Qt::Key)key.toInt(), Qt::NoModifier);
   }
public:
   explicit Keyboard(const QString & title, QWidget *parent = nullptr) : Keyboard(parent) {
      setWindowTitle(title);
   }
   explicit Keyboard(QWidget *parent = nullptr) : QDockWidget(parent) {
      int i{};
      for (auto & btn : m_buttons) {
         btn.setText(QString::number(i));
         btn.setProperty("key", Qt::Key_0 + i);
         m_layout.addWidget(&btn, 0, i, 1, 1);
         connect(&btn, SIGNAL(clicked()), SLOT(clicked()));
         btn.setFocusPolicy(Qt::NoFocus);
         ++i;
      }
      setWidget(&m_widget);
      setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
   }
};

int main(int argc, char ** argv)
{
   QApplication a(argc, argv);
   QMainWindow w;
   w.setCentralWidget(new QLineEdit);
   w.addDockWidget(Qt::TopDockWidgetArea, new Keyboard("Keyboard", &w));
   w.show();
   return a.exec();
}

#include "main.moc"
于 2013-09-02T16:29:36.387 に答える
0

私はそれを行うためのより良い方法を見つけたと思います!使うだけthis->setAttribute(Qt::WA_X11DoNotAcceptFocus);で出来上がり!

例:

MyVirtualKeyboard::MyVirtualKeyboard(QWidget *parent) :
    QDockWidget(parent),
    ui(new Ui::MyVirtualKeyboard)
{
    ui->setupUi(this);
    this->setAttribute(Qt::WA_X11DoNotAcceptFocus);
}
于 2013-09-05T10:06:36.453 に答える