2013-01-21 42 views
0

你可能会发现我对QT很新奇......QT:在运行时更改选项卡遍历顺序?

我的程序包含一个窗口,其中有几个Widget在QGridLayout中。其中一些小部件自身具有布局和子部件。按Tab键移动焦点,就像我期望的那样,按照我创建小部件的顺序。 (我通过删除所有子窗口小部件然后构建新窗口部件来实现这一点)。如果我这样做了,新的窗口小部件将移动到Tab链的末尾(这表明我,该选项卡顺序对于窗口来说是全局的)。我尝试过使用QWidget :: setTabOrder()来重新排列所有小部件(我尝试了两种方法,仅为主窗口的争用设置Tab键顺序并为儿童设置),但实际顺序不变。我通过在小部件的竞争发生变化时发出信号并将其连接到主窗口上的插槽来实现此目的。 我想我理解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); 
} 

更改Tab键顺序时有什么特别的吗?

我也尝试重新实现focusNextPrevChild(bool next)和focusInEvent(QFocusEvent * e)类似于可以在此网站上找到的内容。 1

我设法搞乱了tab选项,更像是这样......这种方法是朝正确方向迈出的一步吗?

对不起,如果这是简单的事情,我设法错过,但我现在挣扎了一段时间,我找不到解决方案。 任何帮助非常感谢。

+0

的我不知道是否能解决问题,但如果'firstWidget'是一样的'小部件[0]',你的循环应该从1开始 –

+0

如何填充“小部件”以及它包含哪些小部件?只有更改其内容的小部件的子项或主布局的所有小部件? –

+0

你有一些被删除的小部件和一些新的小部件。例如,您有1,2,3,4,5个小工具,但接下来您有1,2,5个小工具和6,7个新小工具。如果将Tab键顺序设置为1,2,6,7,5,该怎么办? – Milovidov

回答

0

我遇到了同样的问题,并使用Tim Meyer在评论中提供的信息解决了这个问题。

Tab顺序不是分层的 - 在不接受焦点的父控件上调用setTabOrder不会导致焦点传递给子控件。你需要从Widget中取出适当的孩子并设置它们的顺序

在我的情况下,动态构建的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; 
    } 
    } 
}