[英]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::NoFocus
, QLineEdit
的默認焦點策略是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)
⇄
⇄
輸出:(在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)
⇄
⇄
注意:
我更改了涉及的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.