web-dev-qa-db-ja.com

QWidgetkeyPressEventオーバーライド

QTのQWidgetskeyPressEvent関数をオーバーライドして、半永遠にしようとしていますが、機能しません。私はCPPを初めて使用すると言わざるを得ませんが、ObjCと標準Cを知っています。

私の問題は次のようになります:

class QSGameBoard : public QWidget {
Q_OBJECT

public:
  QSGameBoard(QWidget *p, int w, int h, QGraphicsScene *s);

signals:
  void keyCaught(QKeyEvent *e);

protected:
  virtual void  keyPressEvent(QKeyEvent *event);
};

QSGameBoardは私のQWidgetサブクラスであり、keyPressEventをオーバーライドし、各イベントでSIGNALを起動して、いくつかの登録済みオブジェクトに通知する必要があります。

QSGameBoard.cppでオーバーライドされたkeyPressEventは、次のようになります。

void QSGameBoard::keyPressEvent(QKeyEvent *event) {
  printf("\nkey event in board: %i", event->key());
  //emit keyCaught(event);
}

QSGameBoard ::をQWidget ::に変更すると、イベントを受信しますが、コンパイラがスコープについて文句を言うため、シグナルを送信できません。そして、このように書くと、関数はまったく呼び出されません。

ここでの問題は何ですか?

19
Erik Aigner

編集:他のユーザーが指摘しているように、私が最初に概説した方法は、これを解決するための適切な方法ではありません。 Vasco Rinaldoによる回答

[FocusPolicyをQt :: ClickFocusに設定]を使用して、マウスクリックでkeybordfocusを取得します。 setFocusPolicy(Qt :: ClickFocus);

私が与えた以前の(不完全ではありますが)解決策を以下に示します。

ウィジェットが「フォーカス」されていないようです。マウスプレスイベントを上書きします。

void QSGameBoard::mousePressEvent ( QMouseEvent * event ){
    printf("\nMouse in board");
    setFocus();
}

実用的な例のソースコードは次のとおりです。

QSGameBoard.h

#ifndef _QSGAMEBOARD_H
#define _QSGAMEBOARD_H

#include <QWidget>
#include <QGraphicsScene>

class QSGameBoard : public QWidget {
Q_OBJECT

public:
  QSGameBoard(QWidget *p, int w, int h, QGraphicsScene *s);

signals:
  void keyCaught(QKeyEvent *e);

protected:
  virtual void  keyPressEvent(QKeyEvent *event);
  void  mousePressEvent ( QMouseEvent * event );
};


#endif  /* _QSGAMEBOARD_H */

QSGameBoard.cpp

#include <QKeyEvent>
#include <QLabel>
#include <QtGui/qgridlayout.h>
#include <QGridLayout>

#include "QSGameBoard.h"


QSGameBoard::QSGameBoard(QWidget* p, int w, int h, QGraphicsScene* s) :
    QWidget(p){

    QLabel* o = new QLabel(tr("Test Test Test"));
    QGridLayout* g  = new QGridLayout(this);
    g->addWidget(o);
}

void QSGameBoard::keyPressEvent(QKeyEvent* event){
    printf("\nkey event in board: %i", event->key());
}

void QSGameBoard::mousePressEvent ( QMouseEvent * event ){
    printf("\nMouse in board");
    setFocus();
}

main.cpp

#include <QtGui/QApplication>
#include <QtGui/qmainwindow.h>

#include "QSGameBoard.h"

int main(int argc, char *argv[]) {
    // initialize resources, if needed
    // Q_INIT_RESOURCE(resfile);

    QApplication app(argc, argv);

    QMainWindow oM;
    QGraphicsScene o;
    QSGameBoard a(&oM, 1, 2, &o);
    oM.setCentralWidget(&a);
    a.show();
    oM.show();

    // create and show your widgets here

    return app.exec();
}
14
Gayan

setFocusを呼び出すだけで、自分で再実装する必要はありませんmousePressEvent。 Qtはすでにそれを計画しました。

FocusPolicyQt::ClickFocusに設定して、マウスクリックでkeybordfocusを取得します。

setFocusPolicy(Qt :: ClickFocus);

マニュアルに記載されているように:

このプロパティは、ウィジェットがキーボードフォーカスを受け入れる方法を保持します。

ポリシーは、ウィジェットがタブでキーボードフォーカスを受け入れる場合はQt :: TabFocus、ウィジェットがクリックでフォーカスを受け入れる場合はQt :: ClickFocus、両方を受け入れる場合はQt :: StrongFocus、受け入れない場合はQt :: NoFocus(デフォルト)です。フォーカスをまったく受け入れます。

ウィジェットがキーボードイベントを処理する場合は、ウィジェットのキーボードフォーカスを有効にする必要があります。これは通常、ウィジェットのコンストラクターから実行されます。たとえば、QLineEditコンストラクターはsetFocusPolicy(Qt :: StrongFocus)を呼び出します。

ウィジェットにフォーカスプロキシがある場合、フォーカスポリシーがウィジェットに伝達されます。

12
squid

FocusPolicyをQt :: ClickFocusに設定して、マウスクリックでkeybordfocusを取得します。 setFocusPolicy(Qt :: ClickFocus);

8
Vasco Rinaldo