Как наложить независимые виджеты в Qt? - PullRequest
5 голосов
/ 07 февраля 2012

Я создаю приложение, используя Qt, который состоит из виджета, который используется в качестве фона приложения, и пользовательского интерфейса управления, плавающего над ним.

Аналогичным примером являются карты Google, гдекарта находится в фоновом режиме, а элементы управления - в верхней части фона.

Но дело в том, что фоновый виджет можно изменить на другой виджет (есть виджет, который отображает карту, другой виджет, который отображаетподача видео, ...)

То же самое происходит с кнопками в пользовательском интерфейсе управления, они не связаны напрямую с текущим фоном и могут изменяться динамически.

I 'мы пытались использовать QStackedLayout, используя два слоя, фоновый виджет и интерфейс управления пользователем.Но вы не можете взаимодействовать с фоновым слоем, потому что все щелчки заблокированы виджетом спереди.

Есть предложения?

Ответы [ 3 ]

2 голосов
/ 07 февраля 2012

Вы можете поместить фильтр в поток событий в виджеты вашего интерфейса, используя функцию QObject::installEventFilter(), и перехватывать все входящие события щелчка мышью.После того, как вы захватили эти события, используйте функцию фильтра, чтобы делегировать их либо фоновому виджету, либо передать их кнопкам интерфейса.Скорее всего, вам придется использовать координаты (x, y) щелчка мыши, чтобы определить, должно ли событие перейти к виджету фона или одному из виджетов кнопки переднего плана.

Другой вариант - создатьпроизводный класс от QAbstractButton (или любого другого QWidget, который вы используете для своих кнопок), и повторно реализуйте функции события для щелчков мышью по этому виджету (т. е. QAbstractButton::mousePressEvent() и т. д.).Когда приходит щелчок мыши, проверьте, была ли мышь над кнопкой, а если нет, отправьте событие в фоновый виджет с помощью сигнала или QCoreApplication::sendEvent().

1 голос
/ 07 февраля 2012

Ваш вопрос слишком общий, чтобы дать вам конкретный ответ, но наиболее очевидное решение - реализовать классы, наследуемые от QWidget, для каждого возможного компонента вашей системы. В вашем примере я могу визуализировать 2 отдельных компонента: фон и элементы управления. Фон будет хранить все данные изображения, такие как карты и видео, а элементы управления будут иметь кнопки для взаимодействия с системой. Вы даже можете разбить фон на разные классы для управления изображением или видео. Я рекомендую использовать центральный класс GUIController, который наследуется от QObject, для управления всеми взаимодействиями интерфейса, такими как подключение сигналов / слотов или реализация каких-либо анимаций. Таким образом, вы можете добавлять / управлять несколькими виджетами, не используя разные .cpp.

РЕДАКТИРОВАТЬ: С вашим комментарием кажется, что ваша главная проблема в том, что ваши события мыши не распространяются на ваши виджеты, как вы ожидали. Вероятно, причина этого в том, что вы не устанавливаете родительские / дочерние отношения между компонентами. Убедитесь, что вы вызываете конструктор QWidget по умолчанию в ваших классах пользовательских виджетов, как указано выше:

CustoWidget(QWidget *parent = 0, Qt::WFlags flags = 0) : QWidget(parent, flags)
{
//your code here
}

При создании класса Controller устанавливает правильные отношения между компонентами. В контексте вашей системы мне кажется, что все компоненты будут добавлены как фоновые дочерние элементы, поэтому это будет выглядеть следующим образом:

class Controller : public QObject
{
public:
   Controller(QObject *parent = 0, Qt::WFlags flags = 0) : QObject(parent, flags)
   {
     wdg_back_= new BackWidget(this);
     wdg_control_ = new Controls(wdg_back);
     wdg_1_ = new GenericWidget(wdg_back);

     //connect your signals/slots, etc
   }

private:
   BackWidget *wdg_back_;
   Controls *wdg_control_;
   GenericWidget *wdg_1_;
}
0 голосов
/ 08 февраля 2012

Хорошо, я наконец нашел решение для моей проблемы.

Мой подход к использованию QStackedWidget был неверным, виджет на фоне не предназначен для нажатия, и даже если это возможно, это не то, что я искал.

В конце концов, это то, что я сделал:

QWidget *centralWidget = new QWidget(this);
setCentralWidget(centralWidget);

MapView *backgroundWidget = new MapView(centralWidget);
backgroundWidget->setMinimumSize(1024,600);

QGridLayout *controlsLayout = new QGridLayout(centralWidget);
MyControlWidget *control1 = new MyControlWidget(centralWidget);
control1->setMinimumSize(140,140);
control1->show();

controlsLayout->addWidget(control1,2,0);

Итак, я создаю QWidget, centralWidget, который будет родительским для фона и переднего плана. Установите фон на полный экран и организуйте элементы управления в QGridLayout, который не влияет на backgroundWidget.

Если я нажимаю на элемент управления, событие обрабатывается этим элементом управления, но нажатие на пустое место вызывает событие мыши на backgroundWidget, что мне и нужно.

Я проверю это в течение некоторого времени, и если он будет работать нормально, я закрою вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...