你可能会觉得我对QT很陌生…
我的程序在QGridLayout中包含一个带有几个小部件的窗口。其中一些小部件本身有布局和子小部件。按Tab键移动焦点,就像我所期望的那样,按照我创建小部件的顺序。
当一个小部件改变它的内容时就会出现问题(我通过删除所有的子小部件然后构建新的小部件来做到这一点)。如果我这样做,新的小部件将被移动到选项卡链的末尾(这对我来说,选项卡顺序对窗口来说是全局的)。我尝试使用QWidget::setTabOrder()来重新排序所有小部件(我尝试了这两种方法,仅为主窗口的竞争设置选项卡顺序,并为子窗口设置选项卡顺序),但实际顺序没有改变。我是这样做的:当小部件的竞争发生变化时,发出一个信号,并将其连接到主窗口上的一个插槽。我想我理解setTabOrder()函数应该工作的方式。我做了类似的事情:
QWidget* a = firstWidget;
QWidget* b = secondWidget;
QWidget::setTabOrder(a,b);
for (int i = 0; i < widgets.size(); ++i) {
a = b;
b = widgets[i];
QWidget::setTabOrder(a,b);
}
在改变制表符顺序时,有什么特殊的事情需要做吗?
我还试图重新实现focusNextPrevChild(bool next)和focusInEvent(QFocusEvent* e)类似于在这个网站上可以找到的东西。1
我设法把标签顺序弄乱了很多像这样的…这种方法是朝着正确方向迈出的一步吗?
我很抱歉,如果这是一些简单的东西,我设法错过了,但我现在挣扎了一段时间,我找不到一个解决方案。
我有同样的问题,并使用Tim Meyer在评论中提供的信息解决了它。
制表符顺序不是分层的-在不接受焦点的父小部件上调用setTabOrder将不会导致焦点传递给子小部件。您需要从小部件中获取适当的子节点,并设置它们的顺序
在我的例子中,动态构造的QTreeWidget包含可编辑的小部件,并且我需要重置setTabOrder以解释无序创建的小部件。
下面的代码是
实现的(大部分)// Perform a depth-first gather of the child widgets of this item
void gatherTabWidgets( QObject* item, QWidgetList& tabWidgets )
{
if (item->isWidgetType())
{
QWidget* itemWidget = static_cast<QWidget*>(item);
if (itemWidget->focusPolicy() & Qt::TabFocus)
tabWidgets.push_back( itemWidget );
}
const QObjectList& children = item->children();
for (QObjectList::const_iterator itr = children.begin(); itr != children.end(); itr++)
{
gatherTabWidgets( const_cast<QObject*>(*itr), tabWidgets );
}
}
// Perform a depth-first gather of the child items widgets;
void gatherTabWidgets( QTreeWidgetItem* item, QWidgetList& tabWidgets )
{
QWidget* itemWidget = fetchWidgetForItem( item );
gatherTabWidgets( itemWidget, tabWidgets );
for (int i = 0; i < item->childCount(); i++)
{
gatherTabWidgets( item->child( i ), tabWidgets );
}
}
void VETreeWidget::sortTree()
{
// Ensure ordering is maintained.
sortItems( 0, Qt::AscendingOrder );
// Once the items have been re-ordered, re-create the tab ordering
QTreeWidgetItem* baseItem = topLevelItem( 0 );
QWidgetList tabWidgets;
gatherTabWidgets( baseItem, tabWidgets );
if (!tabWidgets.empty())
{
QWidget* lastWidget = tabWidgets.first();
// Connect this treeview to the first widget. This ensures
// if the treeview is tabbed-to, it will tab to the correct sub-widget
setTabOrder( this, lastWidget );
for (QWidgetList::iterator itr = tabWidgets.begin() + 1; itr != tabWidgets.end(); itr++)
{
setTabOrder( lastWidget, *itr );
lastWidget = *itr;
}
}
}