2015-05-02 33 views
5

Tôi đang tạo một tiện ích con mới, bằng cách phân lớp con lớp QWidget. Tôi muốn có thể thiết lập một tỷ lệ (cho chiều cao và chiều rộng của nó) cho widget này, mà sẽ luôn luôn được duy trì.Giữ tỷ lệ khung hình của một QWidget phân lớp trong khi đổi kích thước

Đối với điều này, tôi luôn tìm kiếm, sử dụng tài liệu Qt5, Google và Stackoverflow. Rõ ràng, tôi đã tìm thấy câu trả lời: cụ thể là this one. Nhưng, thật không may, thậm chí không ai là hoàn toàn hiệu quả:

  • Thiết lập sizeIncrement không hoàn toàn không có gì, thậm chí nếu widget là một cửa sổ
  • Tôi cố gắng để quá tải resizeEvent, nhưng tôi thực sự không biết làm thế nào để làm này ...
  • Nếu tôi làm theo this answer, có hai điều:

    1. Nếu tiện ích là một cửa sổ cấp cao, tỷ lệ không được duy trì ở tất cả, tôi có thể thay đổi kích thước nó như tôi muốn.
    2. Nếu tôi đặt tiện ích này trong bố cục, nếu tôi chỉ tăng cả chiều rộng và chiều cao của cửa sổ, tỷ lệ được duy trì. Nhưng ngay khi tôi tăng chiều rộng hoặc chiều cao lên nhiều, tiện ích được làm phẳng. Thay vào đó, tôi muốn bố cục tự động điều chỉnh kích thước của nó để giữ tỷ lệ của tiện ích con.

Vì vậy, làm cách nào tôi có thể quản lý để giữ tỷ lệ co của QWidget phân lớp?

+0

Đây là một bài đăng khác mà tôi đã làm việc trên hoạt động tốt, ít nhất là cho 'QLabel's. http://stackoverflow.com/questions/8211982/qt-resizing-a-qlabel-containing-a-qpixmap-while-keeping-its-aspect-ratio – phyatt

+0

Bạn đã thử reimplementing 'QWidget :: heightForWidth()' chưa? Điều đó cho phép bạn chỉ định tỷ lệ cỡ ảnh. Nếu không đủ, hãy tạo một phụ huynh "giả" QWidget để giữ widget của bạn trong QG3Layout 3x3, với widget của bạn ở giữa và QSpacerItem xung quanh các cạnh (xem 'QGridLayout :: addItem()'). Các QSpacerItem của có thể cung cấp khoảng cách thêm (hoặc có kích thước xuống 0) khi cần thiết khi thay đổi kích thước. Bạn có thể cần sử dụng 'QGridLayout :: setColumnStretch()' và 'QGridLayout :: setRowStretch()'. – Anthony

+0

Cảm ơn cả hai bạn, giải pháp của bạn hoạt động, nhưng vấn đề tương tự vẫn là: nếu tôi cố gắng tăng chỉ chiều rộng của tiện ích, thì tỷ lệ khung hình không được duy trì nữa. – Spirine

Trả lời

5

Tạo tiện ích con (ví dụ: AspectRatioWidget) để đặt tiện ích của bạn. Đối với phụ huynh, phân lớp QWidget và cho nó một QBoxLayout. Đặt tiện ích của bạn vào giữa và QSpacerItems ở hai bên. Sau đó, trong phụ huynh QWidget::resizeEvent điều chỉnh hướng và kéo dài khi cần thiết. Tôi đã cung cấp một ví dụ bên dưới. Để sử dụng, chỉ cần tạo một thể hiện của AspectRatioWidget và truyền hàm tạo một con trỏ tới tiện ích của bạn và tỷ lệ khung hình mong muốn.

// header 
class AspectRatioWidget : public QWidget 
{ 
public: 
    AspectRatioWidget(QWidget *widget, float width, float height, QWidget *parent = 0); 
    void resizeEvent(QResizeEvent *event); 

private: 
    QBoxLayout *layout; 
    float arWidth; // aspect ratio width 
    float arHeight; // aspect ratio height 
}; 

// cpp 
AspectRatioWidget::AspectRatioWidget(QWidget *widget, float width, float height, QWidget *parent) : 
    QWidget(parent), arWidth(width), arHeight(height) 
{ 
    layout = new QBoxLayout(QBoxLayout::LeftToRight, this); 

    // add spacer, then your widget, then spacer 
    layout->addItem(new QSpacerItem(0, 0)); 
    layout->addWidget(widget); 
    layout->addItem(new QSpacerItem(0, 0)); 
} 

void AspectRatioWidget::resizeEvent(QResizeEvent *event) 
{ 
    float thisAspectRatio = (float)event->size().width()/event->size().height(); 
    int widgetStretch, outerStretch; 

    if (thisAspectRatio > (arWidth/arHeight)) // too wide 
    { 
     layout->setDirection(QBoxLayout::LeftToRight); 
     widgetStretch = height() * (arWidth/arHeight); // i.e., my width 
     outerStretch = (width() - widgetStretch)/2 + 0.5; 
    } 
    else // too tall 
    { 
     layout->setDirection(QBoxLayout::TopToBottom); 
     widgetStretch = width() * (arHeight/arWidth); // i.e., my height 
     outerStretch = (height() - widgetStretch)/2 + 0.5; 
    } 

    layout->setStretch(0, outerStretch); 
    layout->setStretch(1, widgetStretch); 
    layout->setStretch(2, outerStretch); 
} 
Các vấn đề liên quan