当前位置:   article > 正文

QT自适应窗口的一种实现_qt窗口自适应

qt窗口自适应

前言:

QT自身的自适应Layout运用起来,比较复杂,并且需要比较多的时间来调配置各种参数,特别是在原有界面上增加/减少一些控件时的修改,很多时候让人抓狂。本文介绍了一种比较方便的方法来实现这适应窗口大小。

这种方式简单来说就是在Widget创建时,把Widget的初始大小以及其中的控件及其初始大小记录下来,然后在Widget中重载resizeEvent,在此实现中根据Widget的当前大小与初始大小的比例,动态把其中的各控件进行放缩。

为了更方便的实现,可以把这个放缩功能定义在一个基类中,代码如下:

1. UsefulFunsEditor中定义一些公共性质的函数

  1. //UsefulFunsEditor.h
  2. #pragma once
  3. #include <vector>
  4. void NoteWidgetGeometry(std::vector<std::pair<QWidget*, QRect>>& tMap, QWidget* widget);
  5. void ResizeWidget( QWidget* widget, const QRect& srcRect, float scale_x, float scale_y );
  6. void ResizeWidgets( const std::vector<std::pair<QWidget*, QRect>>& tMap, const QSize& parentSrcSize, const QSize& parentDstSize )
  7. /
  8. //UsefulFunsEditor.cpp
  9. #include <QWidget>
  10. //把控件保存入表中
  11. void NoteWidgetGeometry(std::vector<std::pair<QWidget*, QRect>>& tMap, QWidget* widget)
  12. {
  13. if( widget == nullptr )
  14. {
  15. return;
  16. }
  17. std::pair<QWidget*, QRect> tPair;
  18. tPair.first = widget;
  19. tPair.second = widget->geometry();
  20. tMap.push_back(tPair);
  21. }
  22. //控件放缩
  23. void ResizeWidget( QWidget* widget, const QRect& srcRect, float scale_x, float scale_y )
  24. {
  25. QRect tRect = srcRect;
  26. int top = tRect.top();
  27. int bottom = tRect.bottom();
  28. int left = tRect.left();
  29. int right= tRect.right();
  30. top *= scale_y;
  31. bottom *= scale_y;
  32. left *= scale_x;
  33. right *= scale_x;
  34. tRect.setRect(left, top, right-left+1, bottom-top+1);
  35. widget->setGeometry(tRect);
  36. //widget->setAutoFillBackground()
  37. widget->setFixedSize(right-left+1, bottom-top+1);
  38. }
  39. //表中所有控件放缩
  40. void ResizeWidgets( const std::vector<std::pair<QWidget*, QRect>>& tMap, const QSize& parentSrcSize, const QSize& parentDstSize )
  41. {
  42. if( tMap.empty() )
  43. {
  44. return;
  45. }
  46. if( parentSrcSize.width() <= 0 || parentSrcSize.height() <= 0 )
  47. {
  48. return;
  49. }
  50. float scale_x = (float)(parentDstSize.width())/parentSrcSize.width();
  51. float scale_y = (float)(parentDstSize.height())/parentSrcSize.height();
  52. auto itEnd = tMap.end();
  53. QRect rect;
  54. QRect srcRect;
  55. QString name;
  56. for( auto it = tMap.begin(); it != itEnd; ++it )
  57. {
  58. const std::pair<QWidget*, QRect>& tPair = *it;
  59. QWidget* widget = tPair.first;
  60. name = widget->objectName();
  61. srcRect = widget->geometry();
  62. ResizeWidget( tPair.first, tPair.second, scale_x, scale_y );
  63. rect = widget->geometry();
  64. }
  65. }

用于缩放的Widget基类

头文件

  1. /*
  2. ===================================================================
  3. WidgetChildClean.h
  4. 纯静版,没有相关Parent设置
  5. 2022-10-22 edit by lgy
  6. ===================================================================
  7. */
  8. #pragma once
  9. #include <vector>
  10. #include "QWidget"
  11. class WidgetChildClean :public QWidget
  12. {
  13. public:
  14. WidgetChildClean(QWidget *parent = 0, Qt::WFlags flags = 0);
  15. virtual ~WidgetChildClean();
  16. virtual void Update(int delta_ms);
  17. virtual void Active();
  18. protected:
  19. virtual void InitWidgetGeometry();
  20. virtual void resizeEvent(QResizeEvent * event);
  21. protected:
  22. QSize mBaseSrcSize;
  23. std::vector<std::pair<QWidget*, QRect> > mChildrenRectsMap;
  24. };

实现文件

  1. #include "QResizeEvent"
  2. #include "WidgetChildClean.h"
  3. #include "UsefulFunsEditor.h"
  4. WidgetChildClean::WidgetChildClean(QWidget *parent, Qt::WFlags flags):QWidget(parent, flags)
  5. {
  6. }
  7. WidgetChildClean::~WidgetChildClean()
  8. {
  9. }
  10. void WidgetChildClean::Update(int delta_ms)
  11. {
  12. }
  13. void WidgetChildClean::Active()
  14. {
  15. show();
  16. }
  17. void WidgetChildClean::InitWidgetGeometry()
  18. {
  19. mBaseSrcSize = size();
  20. }
  21. void WidgetChildClean::resizeEvent(QResizeEvent * event)
  22. {
  23. QSize curSize = event->size();
  24. ResizeWidgets(mChildrenRectsMap, mBaseSrcSize, curSize);
  25. }

注意:resizeEvent会在每次变化大小时会有调用,我们重点是在新创建的Widget类时,把WidgetChildClean当作一个基类。

实现的例子,注:例子是直接从项目中拿出来的,有大量与项目相关的实现,读者需要只要把相关的地方修改为自己的代码即可,我懒得重新写一个可运行的例子了:

  1. /*
  2. ===================================================================
  3. WidgetBGRecordTable.h
  4. 2022-10-22 edit by lgy
  5. ===================================================================
  6. */
  7. #pragma once
  8. #include "ui_uiBGRecordTable.h"
  9. #include "WidgetChildClean.h"
  10. #include "MovieRecordDB.h"
  11. class CControlClient;
  12. class WidgetBGRecordTable : public WidgetChildClean
  13. {
  14. Q_OBJECT
  15. public:
  16. WidgetBGRecordTable(QWidget *parent = 0, Qt::WFlags flags = 0);
  17. virtual ~WidgetBGRecordTable();
  18. virtual void Update(int delta_ms);
  19. virtual void Active();
  20. void EmptyAll();
  21. void ClearTree();
  22. void FreshRecordHeader(const std::map<int, std::string>& idNameList);
  23. void ShowRecordTree(const DateMovieRecordMap& records);
  24. protected:
  25. virtual void InitWidgetGeometry();
  26. private:
  27. private:
  28. Ui::Form_BGRecordTable ui;
  29. std::map<int, std::string> mIDNameMap;
  30. };
  1. #include "WidgetBGRecordTable.h"
  2. #include "UsefulFunsEditor.h"
  3. WidgetBGRecordTable::WidgetBGRecordTable(QWidget *parent, Qt::WFlags flags):WidgetChildClean(parent, flags)
  4. {
  5. ui.setupUi(this);
  6. InitWidgetGeometry();
  7. }
  8. WidgetBGRecordTable::~WidgetBGRecordTable()
  9. {
  10. }
  11. void WidgetBGRecordTable::Update(int delta_ms)
  12. {
  13. }
  14. void WidgetBGRecordTable::Active()
  15. {
  16. }
  17. void WidgetBGRecordTable::InitWidgetGeometry()
  18. {
  19. mBaseSrcSize = size();
  20. WIDGET_GEOMETRY(treeWidget_Record);
  21. }
  22. void WidgetBGRecordTable::EmptyAll()
  23. {
  24. ui.treeWidget_Record->clear();
  25. QTreeWidgetItem* item = ui.treeWidget_Record->headerItem();
  26. int count = item->columnCount();
  27. for( int i = 0; i < count; ++i )
  28. {
  29. item->setText(i, "");
  30. }
  31. }
  32. void WidgetBGRecordTable::ClearTree()
  33. {
  34. ui.treeWidget_Record->clear();
  35. }
  36. void WidgetBGRecordTable::FreshRecordHeader(const std::map<int, std::string>& idNameList)
  37. {
  38. mIDNameMap = idNameList;
  39. QTreeWidgetItem* head = ui.treeWidget_Record->headerItem();
  40. int count = head->columnCount();
  41. for( int i = 0; i < count; ++i )
  42. {
  43. head->setText(i, "");
  44. }
  45. head->setText(0, QString::fromWCharArray(L"时间"));
  46. int i=0;
  47. for( auto it = idNameList.begin(); it!=idNameList.end(); it++ )
  48. {
  49. i=i+1;
  50. QString name = AsciiStrToQStr(it->second);
  51. head->setText(i, name);
  52. }
  53. }
  54. void WidgetBGRecordTable::ShowRecordTree(const DateMovieRecordMap& records)
  55. {
  56. ui.treeWidget_Record->clear();
  57. if( records.empty() )
  58. {
  59. return;
  60. }
  61. for( auto rit = records.rbegin(); rit != records.rend(); ++rit )
  62. {
  63. QString qnum;
  64. qnum.setNum(rit->first);
  65. QStringList qstrList;
  66. qstrList.append(qnum);
  67. for( auto it = rit->second.begin(); it != rit->second.end(); it++ )
  68. {
  69. int id = it->first;
  70. RecordDef d = it->second;
  71. if( mIDNameMap.count(id)== 0 )
  72. {
  73. qstrList.append("0");
  74. }
  75. else
  76. {
  77. QString qstr_play;
  78. qstr_play.setNum(d.play_c);
  79. qstrList.append(qstr_play);
  80. }
  81. }
  82. QTreeWidgetItem* item = new QTreeWidgetItem(ui.treeWidget_Record, qstrList);
  83. ui.treeWidget_Record->addTopLevelItem(item);
  84. }
  85. }

初始图:

 放缩后的图

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/94848
推荐阅读
相关标签
  

闽ICP备14008679号