Исправлен порядок вкладок после вставки виджетов в макет в QT

У меня есть пользовательская реализация списка (подкласс QWidget) в QT 5.5. Элементы списка организованы с использованием QVBoxLayout, Во время выполнения, элементы (которые также QWidgets) может быть динамически добавлен и удален из списка в любой позиции макета. Это работает нормально, за исключением одной детали: неправильный порядок табуляции вставляемых фокусируемых элементов. Последний вставленный элемент всегда будет последним в порядке табуляции, даже если он вставлен между двумя другими элементами.

Как я могу исправить порядок табуляции для представления порядка макета? Я уже пробовал перебирать элементы списка и использовать setTabOrder() на каждой соседней паре, без успеха.

Еще несколько подробностей о реализации:

  • Виджеты не добавляются непосредственно в список. Каждый раз, когда должен быть добавлен виджет, вместо него создается и добавляется виджет-посредник, реальный виджет будет переставлен в прокси-сервер (прокси-сервер выполняет некоторые графические операции).
  • QVBoxLayout::insertWidget() используется для вставки прокси-виджетов с последующим вызовом QWidget::show()
  • при удалении элементов элемент будет скрыт, удален из прокси, прокси удален из макета списка и освобожден
  • Фокусируемые виджеты могут быть в любом месте дерева объектов элементов, которые добавляются в список, они не обязательно сами элементы

Обновление: добавлено MCVE!

Следующий минимизированный пример демонстрирует проблему. Для полноты я также включил заголовки, основную функцию и файл .pro. Вы можете безопасно пропустить эти файлы, если вы не хотите воспроизводить проблему, TabOrderTestWindow.cpp является важным.

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 = appSOURCES += main.cpp\
TabOrderTestWindow.cpp

HEADERS  += TabOrderTestWindow.h

3

Решение

Здесь действительно, кажется, ошибка, поскольку Doc-состояние, о котором будут заботиться прокси фокуса.

Но мы можем заботиться о них сами, используя:

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

Похоже, вам нужно сделать то, что должен был сделать Qt для вас.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]