赞
踩
前言:
QT自身的自适应Layout运用起来,比较复杂,并且需要比较多的时间来调配置各种参数,特别是在原有界面上增加/减少一些控件时的修改,很多时候让人抓狂。本文介绍了一种比较方便的方法来实现这适应窗口大小。
这种方式简单来说就是在Widget创建时,把Widget的初始大小以及其中的控件及其初始大小记录下来,然后在Widget中重载resizeEvent,在此实现中根据Widget的当前大小与初始大小的比例,动态把其中的各控件进行放缩。
为了更方便的实现,可以把这个放缩功能定义在一个基类中,代码如下:
1. UsefulFunsEditor中定义一些公共性质的函数
-
- //UsefulFunsEditor.h
-
- #pragma once
-
- #include <vector>
-
- void NoteWidgetGeometry(std::vector<std::pair<QWidget*, QRect>>& tMap, QWidget* widget);
- void ResizeWidget( QWidget* widget, const QRect& srcRect, float scale_x, float scale_y );
- void ResizeWidgets( const std::vector<std::pair<QWidget*, QRect>>& tMap, const QSize& parentSrcSize, const QSize& parentDstSize )
-
-
- /
-
- //UsefulFunsEditor.cpp
-
- #include <QWidget>
-
- //把控件保存入表中
- void NoteWidgetGeometry(std::vector<std::pair<QWidget*, QRect>>& tMap, QWidget* widget)
- {
- if( widget == nullptr )
- {
- return;
- }
- std::pair<QWidget*, QRect> tPair;
- tPair.first = widget;
- tPair.second = widget->geometry();
- tMap.push_back(tPair);
- }
-
- //控件放缩
- void ResizeWidget( QWidget* widget, const QRect& srcRect, float scale_x, float scale_y )
- {
- QRect tRect = srcRect;
- int top = tRect.top();
- int bottom = tRect.bottom();
- int left = tRect.left();
- int right= tRect.right();
- top *= scale_y;
- bottom *= scale_y;
- left *= scale_x;
- right *= scale_x;
- tRect.setRect(left, top, right-left+1, bottom-top+1);
- widget->setGeometry(tRect);
- //widget->setAutoFillBackground()
- widget->setFixedSize(right-left+1, bottom-top+1);
- }
-
- //表中所有控件放缩
- void ResizeWidgets( const std::vector<std::pair<QWidget*, QRect>>& tMap, const QSize& parentSrcSize, const QSize& parentDstSize )
- {
- if( tMap.empty() )
- {
- return;
- }
- if( parentSrcSize.width() <= 0 || parentSrcSize.height() <= 0 )
- {
- return;
- }
-
- float scale_x = (float)(parentDstSize.width())/parentSrcSize.width();
- float scale_y = (float)(parentDstSize.height())/parentSrcSize.height();
- auto itEnd = tMap.end();
- QRect rect;
- QRect srcRect;
- QString name;
- for( auto it = tMap.begin(); it != itEnd; ++it )
- {
- const std::pair<QWidget*, QRect>& tPair = *it;
- QWidget* widget = tPair.first;
-
- name = widget->objectName();
-
- srcRect = widget->geometry();
-
- ResizeWidget( tPair.first, tPair.second, scale_x, scale_y );
-
- rect = widget->geometry();
- }
- }
用于缩放的Widget基类
头文件
- /*
- ===================================================================
- WidgetChildClean.h
- 纯静版,没有相关Parent设置
- 2022-10-22 edit by lgy
- ===================================================================
- */
-
- #pragma once
-
- #include <vector>
-
- #include "QWidget"
-
- class WidgetChildClean :public QWidget
- {
- public:
- WidgetChildClean(QWidget *parent = 0, Qt::WFlags flags = 0);
- virtual ~WidgetChildClean();
-
- virtual void Update(int delta_ms);
- virtual void Active();
- protected:
-
- virtual void InitWidgetGeometry();
- virtual void resizeEvent(QResizeEvent * event);
-
- protected:
- QSize mBaseSrcSize;
- std::vector<std::pair<QWidget*, QRect> > mChildrenRectsMap;
- };
-
实现文件
-
- #include "QResizeEvent"
-
- #include "WidgetChildClean.h"
-
- #include "UsefulFunsEditor.h"
-
- WidgetChildClean::WidgetChildClean(QWidget *parent, Qt::WFlags flags):QWidget(parent, flags)
- {
-
- }
- WidgetChildClean::~WidgetChildClean()
- {
-
- }
-
- void WidgetChildClean::Update(int delta_ms)
- {
-
- }
- void WidgetChildClean::Active()
- {
- show();
- }
- void WidgetChildClean::InitWidgetGeometry()
- {
- mBaseSrcSize = size();
- }
- void WidgetChildClean::resizeEvent(QResizeEvent * event)
- {
- QSize curSize = event->size();
- ResizeWidgets(mChildrenRectsMap, mBaseSrcSize, curSize);
- }
注意:resizeEvent会在每次变化大小时会有调用,我们重点是在新创建的Widget类时,把WidgetChildClean当作一个基类。
实现的例子,注:例子是直接从项目中拿出来的,有大量与项目相关的实现,读者需要只要把相关的地方修改为自己的代码即可,我懒得重新写一个可运行的例子了:
- /*
- ===================================================================
- WidgetBGRecordTable.h
- 2022-10-22 edit by lgy
- ===================================================================
- */
-
- #pragma once
-
- #include "ui_uiBGRecordTable.h"
- #include "WidgetChildClean.h"
- #include "MovieRecordDB.h"
-
- class CControlClient;
- class WidgetBGRecordTable : public WidgetChildClean
- {
- Q_OBJECT
- public:
- WidgetBGRecordTable(QWidget *parent = 0, Qt::WFlags flags = 0);
- virtual ~WidgetBGRecordTable();
-
- virtual void Update(int delta_ms);
- virtual void Active();
-
- void EmptyAll();
- void ClearTree();
- void FreshRecordHeader(const std::map<int, std::string>& idNameList);
- void ShowRecordTree(const DateMovieRecordMap& records);
- protected:
-
- virtual void InitWidgetGeometry();
- private:
-
-
-
- private:
- Ui::Form_BGRecordTable ui;
-
- std::map<int, std::string> mIDNameMap;
- };
-
-
- #include "WidgetBGRecordTable.h"
- #include "UsefulFunsEditor.h"
-
- WidgetBGRecordTable::WidgetBGRecordTable(QWidget *parent, Qt::WFlags flags):WidgetChildClean(parent, flags)
- {
- ui.setupUi(this);
- InitWidgetGeometry();
- }
- WidgetBGRecordTable::~WidgetBGRecordTable()
- {
-
- }
-
- void WidgetBGRecordTable::Update(int delta_ms)
- {
-
- }
- void WidgetBGRecordTable::Active()
- {
-
- }
-
- void WidgetBGRecordTable::InitWidgetGeometry()
- {
- mBaseSrcSize = size();
- WIDGET_GEOMETRY(treeWidget_Record);
- }
-
-
- void WidgetBGRecordTable::EmptyAll()
- {
- ui.treeWidget_Record->clear();
- QTreeWidgetItem* item = ui.treeWidget_Record->headerItem();
- int count = item->columnCount();
- for( int i = 0; i < count; ++i )
- {
- item->setText(i, "");
- }
- }
-
- void WidgetBGRecordTable::ClearTree()
- {
- ui.treeWidget_Record->clear();
- }
-
- void WidgetBGRecordTable::FreshRecordHeader(const std::map<int, std::string>& idNameList)
- {
- mIDNameMap = idNameList;
- QTreeWidgetItem* head = ui.treeWidget_Record->headerItem();
- int count = head->columnCount();
- for( int i = 0; i < count; ++i )
- {
- head->setText(i, "");
- }
-
- head->setText(0, QString::fromWCharArray(L"时间"));
-
- int i=0;
- for( auto it = idNameList.begin(); it!=idNameList.end(); it++ )
- {
- i=i+1;
- QString name = AsciiStrToQStr(it->second);
- head->setText(i, name);
- }
- }
-
- void WidgetBGRecordTable::ShowRecordTree(const DateMovieRecordMap& records)
- {
- ui.treeWidget_Record->clear();
- if( records.empty() )
- {
- return;
- }
-
- for( auto rit = records.rbegin(); rit != records.rend(); ++rit )
- {
- QString qnum;
- qnum.setNum(rit->first);
- QStringList qstrList;
- qstrList.append(qnum);
- for( auto it = rit->second.begin(); it != rit->second.end(); it++ )
- {
- int id = it->first;
- RecordDef d = it->second;
- if( mIDNameMap.count(id)== 0 )
- {
- qstrList.append("0");
- }
- else
- {
- QString qstr_play;
- qstr_play.setNum(d.play_c);
- qstrList.append(qstr_play);
-
- }
- }
- QTreeWidgetItem* item = new QTreeWidgetItem(ui.treeWidget_Record, qstrList);
- ui.treeWidget_Record->addTopLevelItem(item);
- }
- }
初始图:
放缩后的图
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。