簡體   English   中英

如何將父窗口小部件焦點重定向到子窗口小部件?

[英]How to redirect parent widget focus to a child widget?

有一個名為FloatingPointPropertyEditor的簡單類。 它繼承自QWidget ,包含一個帶有浮點數驗證器的QLineEdit實例。

class FloatingPointPropertyEditor : public QWidget
{
    Q_OBJECT

    // ...

private:
    QLineEdit* m_lineEdit;
};

問題是我必須將FloatingPointPropertyEditor實例的焦點重定向到內部QLineEdit實例,然后選擇其中的所有文本。 也就是說,當FloatingPointPropertyEditor獲得焦點時,用戶已經可以在QLineEdit實例中輸入文本,而無需之前單擊它。 您能解釋一下我該怎么做嗎?

從Qt。 文檔。 關於QWidget::focusPolicy

focusPolicy:Qt :: FocusPolicy

此屬性保存小部件接受鍵盤焦點的方式

如果窗口小部件通過制表鍵接受鍵盤焦點,則策略為Qt :: TabFocus;如果窗口小部件通過單擊接受焦點,則策略為Qt :: ClickFocus;如果窗口小部件同時接受兩者,則策略為Qt :: StrongFocus;如果不接受,則策略為Qt :: NoFocus(默認)。完全接受焦點。

如果小部件處理鍵盤事件,則必須為其啟用鍵盤焦點。 通常這是從小部件的構造函數完成的。 例如,QLineEdit構造函數調用setFocusPolicy(Qt :: StrongFocus)。

如果窗口小部件具有焦點代理,則焦點策略將傳播給它。

關於提到的焦點代理,關於QWidget::setFocusProxy()

無效的QWidget :: setFocusProxy(QWidget * w)

將小部件的焦點代理設置為小部件w。 如果w為nullptr,則該函數會將此小部件重置為沒有焦點代理。

某些小部件可以“具有焦點”,但是會創建子小部件(例如QLineEdit)來實際處理焦點。 在這種情況下,小部件可以將行編輯設置為其焦點代理。

setFocusProxy()設置在“此小部件”獲得焦點時實際上將獲得焦點的小部件。 如果存在焦點代理,則setFocus()和hasFocus()在焦點代理上運行。


TL; DR

QWidget的默認焦點策略是Qt::NoFocusQLineEdit的默認焦點策略是Qt::StrongFocus 這樣,它應該可以立即使用(盡管有關setFocusProxy()的文檔使此恕我直言不明顯)。

可以肯定的是,我做了一個小的演示testQWidgetFocus.cc

#include <QtWidgets>

class Editor: public QWidget {

  private:
    QHBoxLayout _qHBox;
    QLineEdit _qEdit;
    QPushButton _qBtn0;

  public:
    Editor(QWidget *pQParent = nullptr):
      QWidget(pQParent),
      _qBtn0(">|<")
    {
      _qHBox.addWidget(&_qEdit, 1);
      _qBtn0.setFocusPolicy(Qt::NoFocus); 
      _qHBox.addWidget(&_qBtn0);
      setLayout(&_qHBox);
      // signal handler
      connect(&_qBtn0, &QPushButton::clicked,
        [&](bool) { _qEdit.clear(); });
    }
    virtual ~Editor() = default;
    Editor(const Editor&) = delete;
    Editor& operator=(const Editor&) = delete;

};

int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  QWidget qWinMain;
  QFormLayout qForm;
  QLineEdit qEdit1;
  qForm.addRow("QLineEdit:", &qEdit1);
  Editor qEdit2;
  qForm.addRow("Editor:", &qEdit2);
  qDebug() << "qEdit2.focusPolicy():" << qEdit2.focusPolicy();
  qDebug() << "qEdit2.focusProxy():" << qEdit2.focusProxy();
  Editor qEdit3;
  qForm.addRow("Editor:", &qEdit3);
  qWinMain.setLayout(&qForm);
  qWinMain.show();
  return app.exec();
}

輸出:(在VS2017,Qt 5.13中編譯)

Qt Version: 5.13.0
qEdit2.focusPolicy(): Qt::NoFocus
qEdit2.focusProxy(): QWidget(0x0)

testQWidgetFocus的快照

testQWidgetFocus快照(按Tab后)

testQWidgetFocus快照(按Tab后)

輸出:(在cygwin64中編譯)

$ g++ --version
g++ (GCC) 7.4.0

$ qmake-qt5 testQWidgetFocus.pro

$ make && ./testQWidgetFocus  
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQWidgetFocus.o testQWidgetFocus.cc
g++  -o testQWidgetFocus.exe testQWidgetFocus.o   -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread 
Qt Version: 5.9.4
qEdit2.focusPolicy(): Qt::FocusPolicy(NoFocus)
qEdit2.focusProxy(): QWidget(0x0)

testQWidgetFocus快照(在X11中)

testQWidgetFocus快照(按Tab后)

testQWidgetFocus快照(按Tab后)

注意:

我更改了涉及的QPushButton的焦點策略。 因此,它會在跳跳中被跳過(但仍然可以通過單擊鼠標來使用)。 在不更改其焦點策略的情況下,也可以在跳格中考慮它。


構建腳本:

CMakeLists.txt

project(QWidgetFocus)

cmake_minimum_required(VERSION 3.10.0)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

find_package(Qt5Widgets CONFIG REQUIRED)

include_directories("${CMAKE_SOURCE_DIR}")

add_executable(testQWidgetFocus
  testQWidgetFocus.cc)
target_link_libraries(testQWidgetFocus
  Qt5::Widgets)

# define QT_NO_KEYWORDS to prevent confusion between of Qt signal-slots and
# other signal-slot APIs
target_compile_definitions(testQWidgetFocus PUBLIC QT_NO_KEYWORDS)

testQWidgetFocus.pro

SOURCES = testQWidgetFocus.cc

QT += widgets

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM