gpt4 book ai didi

c++ - 如何将父小部件焦点重定向到子小部件?

转载 作者:行者123 更新时间:2023-11-30 03:14:24 26 4
gpt4 key购买 nike

有一个名为 FloatingPointPropertyEditor 的简单类。它继承自 QWidget 并包含一个带有 float 验证器的 QLineEdit 实例。

class FloatingPointPropertyEditor : public QWidget
{
Q_OBJECT

// ...

private:
QLineEdit* m_lineEdit;
};

问题是我必须将 FloatingPointPropertyEditor 实例的焦点重定向到内部 QLineEdit 实例并选择其中的所有文本。也就是说,当 FloatingPointPropertyEditor 获得焦点时,用户已经可以在 QLineEdit 实例中输入文本,而无需事先单击它。你能解释一下我该怎么做吗?

最佳答案

来自 Qt。医生。关于QWidget::focusPolicy :

focusPolicy : Qt::FocusPolicy

This property holds the way the widget accepts keyboard focus

The policy is Qt::TabFocus if the widget accepts keyboard focus by tabbing, Qt::ClickFocus if the widget accepts focus by clicking, Qt::StrongFocus if it accepts both, and Qt::NoFocus (the default) if it does not accept focus at all.

You must enable keyboard focus for a widget if it processes keyboard events. This is normally done from the widget's constructor. For instance, the QLineEdit constructor calls setFocusPolicy(Qt::StrongFocus).

If the widget has a focus proxy, then the focus policy will be propagated to it.

关于提到的焦点代理,关于QWidget::setFocusProxy() :

void QWidget::setFocusProxy(QWidget *w)

Sets the widget's focus proxy to widget w. If w is nullptr, the function resets this widget to have no focus proxy.

Some widgets can "have focus", but create a child widget, such as QLineEdit, to actually handle the focus. In this case, the widget can set the line edit to be its focus proxy.

setFocusProxy() sets the widget which will actually get focus when "this widget" gets it. If there is a focus proxy, setFocus() and hasFocus() operate on the focus proxy.


长话短说:

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)

Snapshot of testQWidgetFocus

Snapshot of testQWidgetFocus (after pressing Tab)

Snapshot of testQWidgetFocus (after pressing 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)

Snapshot of testQWidgetFocus (in X11)

Snapshot of testQWidgetFocus (after pressing Tab)

Snapshot of testQWidgetFocus (after pressing Tab)

注意:

我更改了涉及的QPushButton 的焦点策略。因此,它在 Tab 跳转中被跳过(但仍然可以通过鼠标单击使用)。在不改变其焦点策略的情况下,它也被考虑在 Tab-jumping 中。


构建脚本:

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

关于c++ - 如何将父小部件焦点重定向到子小部件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57865905/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com