有一个名为FloatingPointPropertyEditor
的简单类。它继承自QWidget
,并包含一个带有浮点数验证器的QLineEdit
实例。
class FloatingPointPropertyEditor : public QWidget
{
Q_OBJECT
// ...
private:
QLineEdit* m_lineEdit;
};
问题是我必须将FloatingPointPropertyEditor
实例的焦点重定向到内部QLineEdit
实例,然后选择其中的所有文本。也就是说,当FloatingPointPropertyEditor
成为焦点时,用户已经可以在QLineEdit
实例中输入文本,而无需先单击它。您能解释一下我该怎么做吗?
答案 0 :(得分:2)
来自Qt。 doc。关于QWidget::focusPolicy
:
focusPolicy:Qt :: FocusPolicy
此属性保存小部件接受键盘焦点的方式
如果窗口小部件通过制表键接受键盘焦点,则策略为Qt :: TabFocus;如果窗口小部件通过单击接受焦点,则策略为Qt :: ClickFocus;如果窗口小部件同时接受两者,则策略为Qt :: StrongFocus;如果窗口小部件接受两者,Qt :: NoFocus(默认值)它根本不接受焦点。
如果小部件处理键盘事件,则必须为其启用键盘焦点。通常这是从小部件的构造函数完成的。例如,QLineEdit构造函数调用setFocusPolicy(Qt :: StrongFocus)。
如果窗口小部件具有焦点代理,则焦点策略将传播给它。
关于提到的焦点代理,关于QWidget::setFocusProxy()
:
void 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