在QT中的布局中插入小部件后修复选项卡顺序 [英] Fix tab order after inserting widgets in a layout in QT

查看:603
本文介绍了在QT中的布局中插入小部件后修复选项卡顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在QT 5.5中有一个自定义列表实现( QWidget 的子类)。列表的元素使用 QVBoxLayout 组织。在运行时,元素(也是 QWidget s)可以在布局中的任何位置动态添加到列表中或从列表中删除。这是工作正常,除了一个细节:插入的可聚焦元素的标签顺序是错误的。插入的最后一个元素将始终是标签顺序中的最后一个元素,即使插入两个其他元素之间。



如何修复Tab顺序以表示布局顺序?我已经尝试遍历列表元素,并在每个相邻对上使用 setTabOrder(),但未成功。



A有关实现的更多详细信息:




  • 小部件不会直接添加到列表中。每次添加一个窗口小部件时,都会创建并添加一个代理窗口小部件,而真实窗口小部件将被重新设置为代理(代理正在做一些图形处理)。

  • code> QVBoxLayout :: insertWidget()用于插入代理窗口小部件,然后调用 QWidget :: show()

  • 在删除元素时,元素将被隐藏,从代理中移除,代理将从列表布局中移除,并被取消分配




更新:添加到列表中的元素的对象树中的任何地方a MCVE!



以下缩小示例演示了此问题。为了完整性,我还包括头文件,主函数和.pro文件。 如果您不想重现问题,可以安全跳过这些文件,TabOrderTestWindow.cpp是重要的。



TabOrderTestWindow.cpp:

  #includeTabOrderTestWindow.h

#include< ; QVBoxLayout>
#include< QPushButton>

//在代理窗口小部件中创建一个按钮
QWidget * createButtonProxy(const QString& caption,QWidget * parent){
QWidget * proxy = new QWidget
QPushButton * button = new QPushButton(caption,proxy);
proxy-> setFocusProxy(button);
return proxy;
}

TabOrderTestWindow :: TabOrderTestWindow()
:QWidget()
{
setMinimumHeight(200);
setMinimumWidth(350);

QVBoxLayout * layout = new QVBoxLayout(this);

//按顺序创建和添加3个按钮
QWidget * button1 = createButtonProxy(button 1,this);
QWidget * button2 = createButtonProxy(button 2,this);
QWidget * button3 = createButtonProxy(button 3,this);
layout-> addWidget(button1);
layout-> addWidget(button2);
layout-> addWidget(button3);

//现在在其他人之间插入第四个按钮 - 不正确的制表顺序!
QWidget * buttonInbetween = createButtonProxy(button in between,this);
layout-> insertWidget(1,buttonInbetween);

//尝试纠正Tab顺序 - 无法工作,即使使用焦点代理设置...
setTabOrder(button1,buttonInbetween);
setTabOrder(buttonInbetween,button2);
}

TabOrderTestWindow.h:

b
$ b

  #ifndef TABORDERTESTWINDOW_H 
#define TABORDERTESTWINDOW_H

#include< QMainWindow>

class TabOrderTestWindow:public QWidget
{
Q_OBJECT

public:
TabOrderTestWindow();
};

#endif // TABORDERTESTWINDOW_H

main.cpp:

  #includeTabOrderTestWindow.h
#include< QApplication>

int main(int argc,char * argv [])
{
QApplication a(argc,argv);
TabOrderTestWindow w;
w.show();

return a.exec();
}

TabOrderTest.pro: b
$ b

  QT + = core gui 

greaterThan(QT_MAJOR_VERSION,4):QT + = widgets
$ b b TARGET = TabOrderTest
TEMPLATE = app


SOURCES + = main.cpp\
TabOrderTestWindow.cpp

HEADERS + = TabOrderTestWindow .h


解决方案

这里真的似乎是一个错误,因为



但是我们可以通过使用:



<$ p来处理他们自己$ p> setTabOrder(button1-> focusProxy(),buttonInbetween-> focusProxy());
setTabOrder(buttonInbetween-> focusProxy(),button2-> focusProxy());

所以看来你需要做Qt应该为你做的事。


I have a custom list implementation (a subclass of QWidget) in QT 5.5. The elements of the list are organized using a QVBoxLayout. At runtime, elements (which are also QWidgets) can be dynamically added to and removed from the list at any position in the layout. This is working fine, except for one detail: the tab order of inserted focusable elements is wrong. The last element inserted will always be the last in the tab order, even if inserted in between two other elements.

How can I fix the tab order to represent the layout order? I already tried iterating over the list elements and using setTabOrder() on each adjacent pair, without success.

A few more details on the implementation:

  • Widgets are not added directly to the list. Each time a widget should be added, a proxy widget is created and added instead, the 'real' widget will be reparented to the proxy (The proxy is doing some graphic stuff).
  • QVBoxLayout::insertWidget() is used to insert proxy widgets, followed by a call to QWidget::show()
  • when removing elements, the element will be hidden, removed from the proxy, the proxy is removed from the list layout and deallocated
  • focusable widgets can be anywhere in the object tree of elements which are added to the list, they are not necessarily the elements themselves

Update: Added a MCVE!

The following minified example demonstrates the problem. For completeness, I also included the headers, main function, and .pro file. You can safely skip those files if you don't want to reproduce the issue, TabOrderTestWindow.cpp is the important one.

TabOrderTestWindow.cpp:

#include "TabOrderTestWindow.h"

#include <QVBoxLayout>
#include <QPushButton>

// create a button inside a proxy widget
QWidget* createButtonProxy(const QString& caption, QWidget* parent) {
    QWidget* proxy = new QWidget(parent);
    QPushButton* button = new QPushButton(caption, proxy);
    proxy->setFocusProxy(button);
    return proxy;
}

TabOrderTestWindow::TabOrderTestWindow()
    : QWidget()
{
    setMinimumHeight(200);
    setMinimumWidth(350);

    QVBoxLayout* layout = new QVBoxLayout(this);

    // create and add 3 buttons in order
    QWidget* button1 = createButtonProxy("button 1", this);
    QWidget* button2 = createButtonProxy("button 2", this);
    QWidget* button3 = createButtonProxy("button 3", this);
    layout->addWidget(button1);
    layout->addWidget(button2);
    layout->addWidget(button3);

    // now insert a fourth button in between the others - incorrect tab order!
    QWidget* buttonInbetween = createButtonProxy("button in between", this);
    layout->insertWidget(1, buttonInbetween);

    // attempt to correct tab order - not working, even with focus proxy set...
    setTabOrder(button1, buttonInbetween);
    setTabOrder(buttonInbetween, button2);
}

TabOrderTestWindow.h:

#ifndef TABORDERTESTWINDOW_H
#define TABORDERTESTWINDOW_H

#include <QMainWindow>

class TabOrderTestWindow : public QWidget
{
    Q_OBJECT

public:
    TabOrderTestWindow();
};

#endif // TABORDERTESTWINDOW_H

main.cpp:

#include "TabOrderTestWindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    TabOrderTestWindow w;
    w.show();

    return a.exec();
}

TabOrderTest.pro:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = TabOrderTest
TEMPLATE = app


SOURCES += main.cpp\
        TabOrderTestWindow.cpp

HEADERS  += TabOrderTestWindow.h

解决方案

Here really seems to be a bug as the Doc state that focus proxies would be cared of.

But we can care of them ourself by using:

setTabOrder(button1->focusProxy(), buttonInbetween->focusProxy());
setTabOrder(buttonInbetween->focusProxy(), button2->focusProxy());

So it seems you need to do what Qt should have done for you.

这篇关于在QT中的布局中插入小部件后修复选项卡顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆