Получить размер ячейки макета QVBoxLayout в Qt4 - PullRequest
1 голос
/ 08 апреля 2011

Я пытаюсь отобразить изображение соответствующего размера внутри QVBoxLayout, но мне не удается получить правильный размер.Макет содержит QLabel, который отображается в хорошем размере в представлении конструктора (см. Изображение).Цель состоит в том, чтобы отобразить изображение в максимально доступном размере.

Layout

Вот мои попытки получить размер (все не удалось):

VideoResourceWidget::VideoResourceWidget(VideoResource* resource, QWidget *parent) :
        QWidget(parent),
        ui(new Ui::VideoResourceForm),
        m_videoResource(resource)
{
    ui->setupUi(this);

    // INFO: -> size = (670,463) // this seems to be too small
    m_videoSize = this->geometry().size();

    // first attempt -> size = (0,0)
    m_videoSize = this->geometry().size();
    m_videoSize.setHeight(m_videoSize.height() - ui->controllerLayout->geometry().height());

    // second attempt -> size = (100,30) way too small
    m_videoSize = ui->videoLayout->itemAt(ui->videoLayout->indexOf(ui->frameLabel))->geometry().size();

    ui->videoLayout->activate(); // hint from another question

    // forth attempt -> size = (145,428) better but not still too small
    m_videoSize = ui->videoLayout->itemAt(ui->videoLayout->indexOf(ui->frameLabel))->geometry().size();

    // third attempt -> size = (670,434) there is still a lot more room
    m_videoSize = this->geometry().size();
    m_videoSize.setHeight(m_videoSize.height() - ui->controllerLayout->geometry().height());

    ui->videoLayout->setSpacing(1);
    ui->frameLabel->setMargin(0);

    ui->videoLayout->activate(); // hint from another question

    // fifth attempt -> size = (145,428) same as before
    m_videoSize = ui->videoLayout->itemAt(ui->videoLayout->indexOf(ui->frameLabel))->geometry().size();

    // sixth attempt -> size = (670,434) same as before
    m_videoSize = this->geometry().size();
    m_videoSize.setHeight(m_videoSize.height() - ui->controllerLayout->geometry().height());

    QImage frame = m_videoResource->firstFrame();
    ui->frameLabel->setPixmap(QPixmap::fromImage(frame).scaled(m_videoSize, Qt::KeepAspectRatio, Qt::SmoothTransformation));

    connect(ui->nextFrameButton, SIGNAL(clicked()), this, SLOT(nextFrame()));
}

Это графический интерфейс после отображения VideoResourceWidget в первый раз.

Displaying the first frame

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

Обновление: Я обновил снимки экрана, чтобы отразить мои последние попытки.

Обновление: минимальный пример:

основное окно.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>771</width>
    <height>580</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QVBoxLayout" name="verticalLayout" stretch="1,0">
    <item>
     <layout class="QHBoxLayout" name="displayLayout" stretch="0,0,0">
      <item>
       <spacer name="horizontalSpacer">
    <property name="orientation">
     <enum>Qt::Horizontal</enum>
    </property>
    <property name="sizeHint" stdset="0">
     <size>
      <width>40</width>
      <height>20</height>
     </size>
    </property>
       </spacer>
      </item>
      <item>
       <widget class="QLabel" name="frameLabel">
    <property name="text">
     <string>TextLabel</string>
    </property>
       </widget>
      </item>
      <item>
       <spacer name="horizontalSpacer_2">
    <property name="orientation">
     <enum>Qt::Horizontal</enum>
    </property>
    <property name="sizeHint" stdset="0">
     <size>
      <width>40</width>
      <height>20</height>
     </size>
    </property>
       </spacer>
      </item>
     </layout>
    </item>
    <item>
     <layout class="QHBoxLayout" name="controllerLayout" stretch="1,0">
      <item>
       <widget class="QScrollBar" name="horizontalScrollBar">
    <property name="orientation">
     <enum>Qt::Horizontal</enum>
    </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="nextButton">
    <property name="text">
     <string>PushButton</string>
    </property>
       </widget>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>771</width>
     <height>25</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

public slots:
    void next();

private:
    Ui::MainWindow *ui;

    QSize m_imageSize;
    QImage m_image;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->layout()->activate();

    connect(ui->nextButton, SIGNAL(clicked()), this, SLOT(next()));

    // Goal: display the image centered using the maximally available space
    m_image = QImage("/tmp/lena.jpg");
    m_imageSize = ui->frameLabel->size();
    ui->frameLabel->setPixmap(QPixmap::fromImage(m_image).scaled(m_imageSize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::next()
{
    // just redraw
    m_imageSize = ui->frameLabel->size();
    ui->frameLabel->setPixmap(QPixmap::fromImage(m_image).scaled(m_imageSize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
}

Ответы [ 2 ]

1 голос
/ 08 апреля 2011

Уменьшите размер полей и интервал (поиграйте с ним. Я не уверен, что к чему) ваших макетов.Таким образом, на этикетке появляется больше места, как и на вашей фотографии.

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

0 голосов
/ 04 февраля 2014

Сначала я попытаюсь удалить проставки. Затем установите метку sizeHint (как уже указал кто-то другой).

Если вам действительно нужны проставки на месте, установите их stretchFactors на «0», а stretchFactor на метке «1».

На самом деле я бы не использовал QLabel для рендеринга видео, но я думаю, что это всего лишь тест, и я знаю, что QLabel прост в использовании для отображения растровых изображений. Мой выбор - пойти на повышение производительности и переопределить QGLWidget и выполнить рендеринг видео через OpenGL.

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