Дочерний элемент QGroupBox ограничивает сжатие формы

#c #qt #qt5

#c #qt #qt5

Вопрос:

У меня многоэкранный видеопроигрыватель, и я просто хочу сохранить соотношение 16: 9. Существует qgroupbox как контейнер qwidget, который воспроизводит в нем видео. Я также использую qgroupbox для отображения выбранного фрейма, окрашивая границу в зеленый цвет. Я не могу этого сделать в qwidget, потому что отображаемое видео перекрывает это. Когда я закончу с изменением размера, я посылаю сигнал с событием mouseup, чтобы иметь возможность сообщить о завершенной операции изменения размера. Затем я вычисляю новые границы для qwidget, чтобы сохранить соотношение 16: 9, и применяю эти значения для qwidget. Вот изображение, чтобы показать вам, как выглядит мое приложение: окно приложения с 4 qgroupboxes И вот код, который я использую для изменения размера qwidgets:

 void playBack::OnWindowResized()
{
    float ratio = 16.0f / 9.0f;
    float w = playBackplayer_contList.at(0)->size().width(); //qgroupbox's width
    float h = playBackplayer_contList.at(0)->size().height();//qgroupbox's height
    float currentRatio = w / h;
    float newW = 0;
    float newH = 0;
    if (currentRatio > ratio)
    {
        newH = h;
        newW = h*ratio;
    }
    else if (currentRatio < ratio)
    {
        newW = w;
        newH = w / ratio;
    }

    qDebug() << "NEW WIDGET SIZE: " << (int)newW << " x " << (int)newH;

    for (int i = 0; i < playBackplayer_widgtList.count(); i  )
    {
        playBackplayer_widgtList.at(i)->setMinimumSize(newW, newH);
        //playBackplayer_widgtList.at(i)->resize(newW, newH);
    }
}
  

Этот код отлично работает, когда я увеличиваю форму, но когда я хочу уменьшить, он не позволяет мне этого сделать. Потому что я установил минимальное значение для qwidgets. Если я не использую setMinimumSize, вместо этого используйте resize (w, h), чем возникают проблемы с ориентацией. И вот пример для решения этой проблемы:

проблема с ориентацией при использовании resize()

В приведенном ниже коде показан ctor, и здесь я устанавливаю макет:

 playBack::playBack()
{
    playback_player_1_widget = new QWidget;
    playback_player_2_widget = new QWidget;
    playback_player_3_widget = new QWidget;
    playback_player_4_widget = new QWidget; 

    playback_player_1_widget_cont = new QGroupBox;
    playback_player_2_widget_cont = new QGroupBox;
    playback_player_3_widget_cont = new QGroupBox;
    playback_player_4_widget_cont = new QGroupBox;

    playBackplayer_widgtList.append(playback_player_1_widget);
    playBackplayer_widgtList.append(playback_player_2_widget);
    playBackplayer_widgtList.append(playback_player_3_widget);
    playBackplayer_widgtList.append(playback_player_4_widget);

    playBackplayer_contList.append(playback_player_1_widget_cont);
    playBackplayer_contList.append(playback_player_2_widget_cont);
    playBackplayer_contList.append(playback_player_3_widget_cont);
    playBackplayer_contList.append(playback_player_4_widget_cont);

    int rowcnt = 0;
    int colcnt = 0;
    for (int i = 0; i < 4; i  )
    {
        playBackplayer_contList.at(i)->setStyleSheet(QString("border:1px solid #000;background-color:#000;"));
        playBackplayer_widgtList.at(i)->setStyleSheet(QString("background-color:#f00;"));
        QGridLayout* layout = new QGridLayout;
        layout->setRowStretch(0, 1);
        layout->setColumnStretch(0, 1);
        layout->setRowStretch(2, 1);
        layout->setColumnStretch(2, 1);
        playBackplayer_widgtList.at(i)->setMinimumWidth(100);
        playBackplayer_widgtList.at(i)->setMinimumHeight(100);
        playBackplayer_widgtList.at(i)->setMaximumWidth(10000);
        playBackplayer_widgtList.at(i)->setMaximumHeight(10000);

        layout->addWidget(playBackplayer_widgtList.at(i),1,1);
        layout->setMargin(0);
        layout->setSpacing(0);

        playBackplayer_contList.at(i)->setLayout(layout);

        mainLayout->addWidget(playBackplayer_contList.at(i), colcnt, rowcnt);

        rowcnt  ;
        if (rowcnt % 2 == 0)
        {
            rowcnt = 0;
            colcnt  ;
        }

        playBackplayer_widgtList.at(i)->setAcceptDrops(true);
    }
}
  

Я пробовал разные вещи, я пытался установить размер 0 для qwidget перед изменением размера (в mousedownevent), но это не сработало, я пытался удалить макет для qgroupbox, после изменения размера создайте новый макет и установите его для groupbox, это не сработало, я пробовал layout ()-> adjustSize (), update (), repaint (), все это не сработало. Чего я не понимаю? Мне нужна ваша помощь. Любая помощь была бы оценена. Заранее благодарю вас.

Комментарии:

1. измените mainLayout->addWidget(playBackplayer_contList.at(i), colcnt, rowcnt); на mainLayout->addWidget(playBackplayer_contList.at(i), colcnt, rowcnt, Qt::AlignCenter);

Ответ №1:

Устраните макет сетки внутри групповых блоков контейнера. Вместо этого выровняйте и измените размер виджета видео с помощью setGeometry

Вот простой подкласс QGroupBox , который я создал, который сохраняет желаемое соотношение и всегда остается в центре:

 class RatioGroupBox : public QGroupBox{
    Q_OBJECT
public:
    RatioGroupBox(QWidget *parent = nullptr) : QGroupBox (parent){
        setFlat(true);
        setStyleSheet("border:1px solid #000;background-color:#000;");
        setMinimumSize(100, 100);
        setMaximumSize(10000, 10000);
        ratio = 16.0f/9.0f;
        ratioWidget = new QWidget(this);
        ratioWidget->setStyleSheet("background: #f00;");
        ratioWidget->setAcceptDrops(true);
    }

protected:
    void resizeEvent(QResizeEvent *){//or you can use your own resize slot
        float w = width();
        float h = height();
        float currentRatio = w/h;
        float newW(0);
        float newH(0);
        if (currentRatio > ratio){
            newH = h;
            newW = h*ratio;
        }
        else if (currentRatio < ratio){
            newW = w;
            newH = w / ratio;
        }

        ratioWidget->setGeometry((w-newW)/2, (h-newH)/2, newW, newH);
    }

private:
    QWidget *ratioWidget;
    float ratio;
};
  

Весь ваш ctor станет чем-то вроде:

 playBack::playBack()
{
    for(int r=0; r<2; r  ){
        for(int c=0; c<2; c  ){
            RatioGroupBox* playback_player_cont = new RatioGroupBox;
            mainLayout->addWidget(playback_player_cont, c, r);
            playBackplayer_contList.append(playback_player_cont);
        }
    }
}
  

Вы, конечно, можете получить доступ к своим виджетам видео, выставив их ratioWidget любым удобным для вас способом. Либо делая его общедоступным, либо создавая функцию получения.