QT应用程序分辨率自适应

转载 2017年05月19日 13:47:58

先贴上我自己根据以下文章写的自适应分辨率代码:

//.h文件
#ifndef AUTORESIZEWIDGET_H
#define AUTORESIZEWIDGET_H

#include <QtWidgets/QMainWindow>
#include <qmovie.h>
#include "ui_autoresizewidget.h"

struct AutoResize
{
	QRect m_rect;
	QFont m_font;
};

class autoResizeWidget : public QMainWindow
{
	Q_OBJECT

public:
	autoResizeWidget(QWidget *parent = 0);
	~autoResizeWidget();

protected:
	void mousePressEvent(QMouseEvent *);
	void mouseReleaseEvent(QMouseEvent *);
	void mouseMoveEvent(QMouseEvent *);
	void keyPressEvent(QKeyEvent *);
	void resizeEvent(QResizeEvent *);
private:
	void FindWidgetAllChildren();
private:
	Ui::autoResizeWidgetClass ui;
	QPoint m_point;
	bool m_bPress;

	// 保存最开始的大小和字体
	QRect m_rect;  
	QFont m_font;
	QMap<QWidget*, AutoResize> m_wdgtMapSize; //保存所有窗口最开始大小和字体
	QMovie *m_movie;
};

#endif // AUTORESIZEWIDGET_H


//.cpp文件
#include "autoresizewidget.h"
#include <qdesktopwidget.h>
#include <QMouseEvent>

/*
根据屏幕大小自适应窗口大小,包括窗口字体,所有窗体,gif都自适应大小。也支持窗口拖拉自适应大小。
*/

autoResizeWidget::autoResizeWidget(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	m_movie = new QMovie("./resouce/scandigitalvein.gif");
	ui.movielb->setMovie(m_movie);
	m_movie->start();

	m_rect = this->geometry();
	m_font = this->font();
	int pointsize = m_font.pointSize();
	m_font.setPixelSize(pointsize * 90 / 72); //设置字体大小单位为像素大小,而不是以磅为单位
	this->setFont(m_font);

	QDesktopWidget *widget = QApplication::desktop();

	// 触发resizeEvent函数调用
	QRect rect = widget->geometry();
	this->setGeometry(rect);
	
	
	FindWidgetAllChildren();
}

autoResizeWidget::~autoResizeWidget()
{
	if (m_movie != NULL)
	{
		m_movie->stop();
		delete m_movie;
		m_movie = NULL;
	}
}

void autoResizeWidget::FindWidgetAllChildren()
{
	QList<QWidget*> wls = this->findChildren<QWidget*>();
	QList<QWidget*>::iterator it = wls.begin();
	int i = 0;
	for (; it != wls.end(); it++)
	{
		AutoResize auresize;
		auresize.m_rect = (*it)->geometry();
		auresize.m_font = (*it)->font();
		m_wdgtMapSize[(*it)] = auresize;
		i++;
		printf("i:[%d] [%s]\n", i,(*it)->objectName().toLocal8Bit().data());
	}
	
}

void autoResizeWidget::resizeEvent(QResizeEvent *e)
{
	if (m_rect.width() == 0 || m_rect.height() == 0)
	{
		QMainWindow::resizeEvent(e);
		return;
	}

	//取得长宽的缩放比
	float scalew = this->width()*1.0 / m_rect.width();
	float scaleh = this->height()*1.0 / m_rect.height();

	// 取最小的一个
	float fontscale = scalew > scaleh ? scaleh : scalew;

	// 再在原来大小基础上根据缩放比例调整大小
	QMap<QWidget*, AutoResize>::iterator it = m_wdgtMapSize.begin();
	for (; it != m_wdgtMapSize.end(); it++)
	{
		QWidget *item = it.key();
		int x = (it.value().m_rect.x())*scalew; // 在最开始的大小的基础上乘以缩放比例
		int y = (it.value().m_rect.y())*scaleh;
		int w = (it.value().m_rect.width())*scalew;
		int h = (it.value().m_rect.height())*scaleh;
		item->setGeometry(QRect(x, y, w, h));

		QFont font = it.value().m_font;
		// 取得最开始的字体大小
		int fontsize = font.pixelSize();
		if (fontsize == -1)
		{
			fontsize = font.pointSize();
			if (fontsize == -1)
			{
				qreal sizef = font.pointSizeF();
				font.setPointSizeF(sizef* fontscale);
			}
			else
			{
				font.setPixelSize(fontsize * fontscale * 90 / 72); // 设置字体大小为像素大小,而不是以磅为单位,
				//font.setPointSize(fontsize * fontscale);
			}
		}
		else
		{
			font.setPixelSize(fontsize * fontscale);
		}
		
		item->setFont(font);

		// //设置gif根据窗口大小变化  m_movie所对应的lb
		if (item->objectName() == "movielb")
		{
			m_movie->setScaledSize(item->size());
		}
	}
	QMainWindow::resizeEvent(e);
}


void autoResizeWidget::mousePressEvent(QMouseEvent *e)
{
	if (e->button() == Qt::LeftButton)
	{
		m_bPress = true;
		m_point = e->globalPos() - this->pos();
		e->accept();
	}
}

void autoResizeWidget::mouseReleaseEvent(QMouseEvent *e)
{
	m_bPress = false;
}

void autoResizeWidget::mouseMoveEvent(QMouseEvent *e)
{
	if (m_bPress)
	{
		move(e->globalPos() - m_point);
		e->accept();
	}
}

void autoResizeWidget::keyPressEvent(QKeyEvent *e)
{
	if (e->key() == Qt::Key_Escape)
	{
		this->close();

	}
}

可以参考下我上传的资源:

qt窗口自适应v2.0

http://download.csdn.net/download/qqwangfan/9879571



QT应用程序分辨率自适应

http://blog.csdn.net/matengxiao/article/details/52853332


以上文章如下:

QT应用程序分辨率自适应

一、应用程序分辨率自适应

    为了满足应用程序能在不同尺寸及分辨率的屏幕下能够正常的运行显示,就需要对不同的分辨率进行自适应,而且应用程序分辨率自适应的问题在应用UI设计布局以及UI代码编写阶段进行设计规划,如在界面完成后期再考虑分辨率问题可能需要更大的工作量,并且自适应效果不一定能达到要求。一般来说,应用程序的设计应该按照支持的最小分辨率来进行设计,在应用程序分辨率变化时应用程序中的各个元素进行尺寸的缩放以及位置的调整,同时增加或减少应用程序显示界面内容,同时还要考虑图片失真,控件变形,字体显示等问题。 
    对于Qt应用来说,官方并没有提供一整套完整的解决有效方案,因此Qt程序的分辨率自适应问题需要按照应用程序的要求,在程序中自己实现相应的控件适应,但是分辨率适配的大体思路都是一致的,即调整控件尺寸及位置以及修改界面元素显示内容,Qt程序又可分为QtWidget程序以及qml程序,下面分别描述这两部分程序的界面分辨力的自适应解决方案。

二、QtWidget中的分辨率自适应

    在QtWidget中Qt已经提供有相应的解决方案来实现控件分辨率的自适应,即通过layout对控件进行布局来实现控件的自适应,此外还可以通过自定义QTWidget中控件的自适应策略来实现分辨率自适应,下面分别介绍这两种方法:

2.1layout布局

    通过layout布局的方式对QtwWidget的分辨率自适应,即将需要将自适应的控件添加进layout布局中,当layout的父对象的尺寸变化时,layout会根据父对象相应的变化宽、高比例对布局中的控件进行缩放,以此来实现相应控件的分辨率自适应。 
    通过layout的方式实现控件的方式实现自动缩放使用简单,且无须关注其具体的实现细节,但是这种方式需要就界面刚开始布局时,就要需要采用layout的方式进行布局,但是对于已经完成且没有采用layout布局的界面,可在QtCreator设计器中将需要添加布局的控件选中,然后点击右键,选择栅格化即可。 
但是在QtCreator Designer中添加的layout存在一个问题,如下图在Designer中添加一个Vertical Layout,layout中添加两个PushButton,当运行程序后,调整程序大小,中间的PushButton并不会随着窗口大小而进行缩放。

UI图 
原始 
缩放窗口 
    通过查看QtCreator中通过ui文件生成的头文件,即ui_widget.h中的代码可以发现,在QtDesigner中添加layout时,会给layout自动添加一个widget的父对象,即下图中的verticalLayoutWidget,因此verticalLayout会随着其父对象verticalLayoutWidget的大小变化,对其中的控件进行缩放调整,因此才会出现上面的程序窗口变化时,layout中的控件不会自动缩放。 
这里写图片描述 
    对于上述情况,需要在窗口大小变化时先调整verticalLayoutWidget的位置及大小,这样verticalLayout就会随着窗口大小的变化而自动调整其中的控件,具体操作如下 
重载widget的resizeEvent函数,依据窗口大小的变化调整动态verticalLayoutWidget

     QWidget * resizeWidget=ui->verticalLayoutWidget;
     QRect resizeRect=resizeWidget->rect();
     static float baseWidth=400;
     static float baseHeight=300;
     static float widgetWidth=resizeRect.width();
     static float widgetHeight=resizeRect.height();
     static float widgetX=ui->verticalLayoutWidget-
>geometry().x();
     static float widgetY=ui->verticalLayoutWidget->geometry().y();
     qDebug()<<resizeRect<<widgetX<<widgetY;
     float horRatio=this->rect().width()/baseWidth;
     float verRatio=this->rect().height()/baseHeight;
     //dajust the position of verticalLayoutWidget
     resizeRect.setX(widgetX*horRatio);
     resizeRect.setY(widgetY*verRatio);

     //resize the verticalLayoutWidget
     resizeRect.setWidth(widgetWidth*horRatio);
     resizeRect.setHeight(widgetHeight*verRatio);
     //set Geometry
     resizeWidget->setGeometry(resizeRect);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

原始程序 
缩放 
    对于控件的缩放和位置调整,都是依据程序窗口的变化来调整的,这里选用horRatio,verRatio两个变量来记录窗口的宽度方向和高度方向的缩放比例,对于verticalLayoutWidget的宽度和高度来说直接按窗口的缩放比例按等比例缩放即可,对于X,Y按比例缩放 
resizeRect.setX(widgetX*horRatio); 
resizeRect.setY(widgetY*verRatio);

2.1自定义控件缩放

    利用layout对控件进行布局缩放使用简单,且无需关注内部细节,但是利用layout进行布局时,控件的位置和大小受布局的约束无法实现大小和位置的精确控制,对于界面又复杂布局要求时layout并不能满足使用要求,对于这部分控件只能自定义控件的缩放,在程序窗口缩放是实现分辨率的自适应。 
具体的缩放规则与前面类似,在程序窗口尺寸变化时,即首先获得程序窗口的缩放比例horRatio,verRatio放,然后对各个控件的X,Y以及宽度width和高度height进行相应比例的缩放即可,但是对于每个单独的控件都进行自定义缩放,实现起来较复杂,因此需要采用通用的方法来对各个控件进行缩放。 
    由于大部分的可以控件都是继承于QWidget的,因此查找到程序中所有的QWidget对象,然后在实现相应的变换即可。Qt提供了findChildren方法可以查找特定类型的子对象,因此可以利用这个方法来实现查找QWidget的子对象,并进行自定义缩放: 
首先定义结构体来存储控件的基本尺寸及位置

struct AutoResizeOriginalData
{
    QRect data_rect;
    QFont data_font;
};
//define a map to store the resize items
QMap<QWidget*,AutoResizeOriginalData> m_resizeMap;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

然后在查找窗口中全部的QWidget对象,并记录其初始位置

QWidget *item=NULL;
AutoResizeOriginalData resizeData;
QRect tmp;
QList<QLabel*> _labelList=m_autoResizeObj->findChildren<QLabel *>();
for(auto it=_labelList.begin();it!=_labelList.end();it++)
{
    item=*it;
    tmp=item->geometry();
    tmp.setX(item->x());
    tmp.setY(item->y());
    tmp.setWidth(abs(tmp.width()));
    tmp.setHeight(abs(tmp.height()));
    resizeData.data_rect=tmp;
    resizeData.data_font=item->font();
    m_resizeMap[item]=resizeData;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

再重载窗口对象的resizeEvent函数,对各个控件进行自适应控制

m_horRatio=this->rect().width()/m_baseWidth;
m_verRatio=this->rect().height()/m_baseHeight;
QMapIterator<QWidget*, AutoResizeOriginalData> _itarator(m_resizeMap);
        while(_itarator.hasNext())
        {
            _itarator.next();
            QWidget* _item=_itarator.key();
            QRect tmp=_itarator.value().data_rect;
            tmp.setWidth(tmp.width()*m_horRatio);
            tmp.setHeight(tmp.height()*m_verRatio);
            QRect after=QRect(tmp.x()*m_horRatio,tmp.y()*m_verRatio,tmp.width(),tmp.height());    
_item->setGeometry(after);
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

    如果界面中有一部分控件包含在layout中,在查找QWidget对象时会把这一部分控件也包含在其中,这样的话在进行尺寸缩放时回合layout相互影响,导致界面发成错位,应去除这些控件,交由layout来控制其缩放,具体操作如下: 
首先定义一个函数用于移除其所有子对象

void AutoResize::ignoreAllChiledren(QObject* obj)
{
    QList<QObject*> children=obj->children();
    for(auto it=children.begin();it!=children.end();it++)
    {
        QWidget *item=qobject_cast<QWidget*>(*it);
        m_ignoreItem.push_back(item);
        AutoResizeOriginalData resizeData;
        if(!item)
            continue;
        m_resizeMap.remove(item);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

查找所有的layout:

QString desName="widget";
QList<QLayout*> layoutList=m_autoResizeObj->findChildren<QLayout*>();
for(auto it=layoutList.begin();it!=layoutList.end();it++)
{
    QString objName=(*it)->parent()->objectName();
    if(objName.contains(desName))
    {
        //need to find the items in layout by the parent widget of layout                
        QWidget* layoutWidget=qobject_cast<QWidget*>((*it)->parent());
        ignoreAllChiledren(layoutWidget);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.3字体缩放

    Qt中的字体Qfont定义字体大小是有两种方式,一种是PixelSize,另一种是PointSize,PixelSize实际上是以像素为单位,即PixelSize的大小即为实际的像素大小。PointSize的单位不是像素,它是以字体在屏幕实际显示的大小为单位的,它和屏幕的分辨率以及屏幕的真实尺寸相关,即它的单位即为屏幕上显示的字体大小。 
    对于相同尺寸不同分辨率的屏幕,通过设置PointSize大小的字体,不同分辨率的屏幕上显示的实际字体的大小是一样的,通过设置PointSize的字体来说,字体大小是随着屏幕大小以及分辨率自适应的,因此无须处理字体的缩放;但是对于设置PixelSize大小的字体来说,由于所占分辨率大小固定,因此在相同尺寸上更高分辨率的屏幕上,由于其单位长度内的像素点数更多,即像素密度更大,因此对于更好分辨率的屏幕来说,字体会看起来小一些,要处理这种情况,一种办法就是所有字体都用PointSize来表示大小,但对于已经采用PixelSize的字体来说,就要对其进行控制缩放。 
首先创建用于缩放字体的函数

void AutoResize::fontAutoResize(QWidget *obj,int fontSize) 

if(fontSize<=0) 
return; 
bool hasTextStyle=false; 
fontSize*=m_fontRatio; 
QFont changedFont; 
changedFont=obj->font(); 
changedFont.setPixelSize(fontSize); 
obj->setFont(changedFont); 
}

    由于控件都继承与QWidget,且QWidget具有字体属性,因此可以通过QWidget来查找自控件,并记录相应的字体信息

QWidget *item=NULL;
AutoResizeOriginalData resizeData;
QRect tmp;
QList<QLabel*> _labelList=m_autoResizeObj->findChildren<QLabel *>();
for(auto it=_labelList.begin();it!=_labelList.end();it++)
{
    item=*it;
    tmp=item->geometry();
    tmp.setX(item->x());
    tmp.setY(item->y());
    tmp.setWidth(abs(tmp.width()));
    tmp.setHeight(abs(tmp.height()));
    resizeData.data_rect=tmp;
    resizeData.data_font=item->font();
    m_resizeMap[item]=resizeData;
    //the pixelsize !=-1 when set font size by pixelsize
    if(resizeData.pixelSize()!=-1)
    {
        m_fontMap[item]=resizeData;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
计算字体缩放比例
void AutoResize::calculateResizeRatio()
{
    m_horRatio=m_autoResizeObj->width()/m_baseWidth;
    m_verRatio=m_autoResizeObj->height()/m_baseHeight;
    m_fontRatio=m_horRatio<m_verRatio?m_horRatio:m_verRatio;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

重载resizeEvent函数,缩放字体

void AutoResize::doAutoResize()
{
    calculateResizeRatio();
    if(m_autoResize)
    {
        QMapIterator<QWidget*,AutoResizeOriginalData> _fontIt(m_fontMap);
        while(_fontIt.hasNext())
        {
            _fontIt.next();
            QWidget* _item=_fontIt.key();
              changedFont=_fontIt.value().data_font;
              fontAutoResize(_item,changedFont.pointSize());
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

本章节相应的代码和示例请查看本人GitHub

三、qml中的分辨率自适应

    qml中没有提供类似QtWidget中的layout进行布局,因此qml中的所有控件的分辨率自适应都需要自定义实现,其自适应原理与QtWidget中类似,都是在程序窗口发生变化时,对窗口尺寸变化事件进行响应,依据父窗口的中宽度以及高度的缩放比例,分辨对各个子对象进行位置以及尺寸的变换。 
下面实现一种通用的分辨率自适应的组件

// AutoResize.qml
import QtQuick 2.0

Item {
    id:globalResize
    property var targetItem: parent  // the parent of all items
property bool fixedAspectRatio: false // Else zoom from width and height
property bool fontAccordingToMax: false
    property bool ifAutoResize: true
    property string ignoreAll: "ignoreAll"
    property string ignoreChildren: "ignoreChildren"
    //变换比例
    property real horizontalRatio: 1.0
    property real verticalRatio: 1.0
    property real fontRatio: 1.0

    property var targetItemGeometry
    property var childrenItemGeometry
    property var childrenText
    property real fontSizeScaleFactor: 1.0
    property bool isBegin: false
    signal resized()
    Component.onCompleted: {
        begin();
    }

    Component {
        id: connections

        Connections {
            target: targetItem

            onWidthChanged: {
                resize();
            }
            onHeightChanged:
            {
                resize();
            }
        }
    }
    Loader {
        Component.onCompleted: {
            sourceComponent = connections;
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

定义begin( )函数用于才开始时获取程序窗口中要进行缩放的所有子对象的,并记录其基本的尺寸信息,具体试下如下

function begin() {
        var _childrenItemGeometry=new Array;
        targetItemGeometry = new Object;
        targetItemGeometry["width"] = targetItem.width;
        targetItemGeometry["height"] = targetItem.height;
        var children = targetItem.children;
        for(var index = 1; index < children.length; index++)
        {
            var currentItem = children[index];
            var buf = new Object;

            buf["item"] = currentItem;
            buf["name"]=currentItem.objectName;
            buf["x"] = currentItem.x;
            buf["y"] = currentItem.y;
            buf["centerX"] = currentItem.x + (currentItem.width / 2);
            buf["centerY"] = currentItem.y + (currentItem.height / 2);
            buf["width"] = currentItem.width;
            buf["height"] = currentItem.height;

            //to scale the font size
            buf["fontSize"]=0;
            if(currentItem.font!=undefined)
            {
                buf["fontSize"]=currentItem.font.pointSize
            }
            if(buf["name"]==ignoreAll)
            {
                continue;
            }
            else if(buf["name"]==ignoreChildren)
            {
                _childrenItemGeometry.push(buf)
            }
            else
            {
                _childrenItemGeometry.push(buf)
                getAllChildren(_childrenItemGeometry,currentItem)
            }
        }
        childrenItemGeometry=_childrenItemGeometry
        isBegin = true;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

    getAllChildren用于获取某个对象的全部子对象,由于qml中的children只能获得当前对象的直系子对象,对孙子对象等是获取不到的,因此需要递归调用才能获取全部子对象

function getAllChildren(_childrenItemGeometry,target)
    {
        var children = target.children;
        for(var index = 0; index < children.length; index++)
        {
            var currentItem = children[index];
            var buf = new Object;
            buf["item"] = currentItem;
            buf["name"]=currentItem.objectName;
            buf["x"] = currentItem.x;
            buf["y"] = currentItem.y;
            buf["centerX"] = currentItem.x + (currentItem.width / 2);
            buf["centerY"] = currentItem.y + (currentItem.height / 2);
            buf["width"] = currentItem.width;
            buf["height"] = currentItem.height;
            buf["fontSize"]=0;
            if(currentItem.font!=undefined)
            {
                buf["fontSize"]=currentItem.font.pointSize
            }
            if(buf["name"]=="ingnoreAll")
            {
                continue;
            }
            else if(buf["name"]=="ingnoreChildren")
            {
                _childrenItemGeometry.push(buf)
            }
            else
            {
                _childrenItemGeometry.push(buf)
                getAllChildren(_childrenItemGeometry,currentItem)
            }
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

    resize函数是在targetItem对象的宽度或这高度发生变化时出发的,用于实现所有子对象的缩放

    function resize() {
        if(isBegin&&ifAutoResize)
        {
            //calculate the ratio
            horizontalRatio = targetItem.width / targetItemGeometry["width"];
            verticalRatio = targetItem.height / targetItemGeometry["height"];
            fontRatio=horizontalRatio>verticalRatio?verticalRatio:horizontalRatio;
            for(var index = 0; index < childrenItemGeometry.length; index++)
            {
                var currentItem=childrenItemGeometry[index]
        //adjust the size of item
                childrenItemGeometry[index]["item"].width  = childrenItemGeometry[index]["width"] * horizontalRatio;
                childrenItemGeometry[index]["item"].height = childrenItemGeometry[index]["height"] * verticalRatio;
        //adjust the position of item
                childrenItemGeometry[index]["item"].x = childrenItemGeometry[index]["x"] * horizontalRatio;
                childrenItemGeometry[index]["item"].y = childrenItemGeometry[index]["y"] * verticalRatio;

                if(childrenItemGeometry[index]["item"].font!=undefined)
                {
                    childrenItemGeometry[index]["item"].font.pixelSize = childrenItemGeometry[index]["fontSize"]*fontRatio*fontSizeScaleFactor
                }
            }
           //emit the resize signal
            globalResize.resized();
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

AutoResize.qml的使用示例

//AutoResizeDemo
import QtQuick 2.6
import QtQuick.Controls 2.0

Rectangle {
    visible: true
    width: 400
    height: 300
    AutoResize{
        id:resizeHandler
    }
    Rectangle{
        x:20
        y:20
        color: "red"
        width: 100
        height: 50
    }
    Rectangle{
        x:200
        y:20
        color: "yellow"
        width: 100
        height: 50
        Text {
            anchors.centerIn: parent
            text: qsTr("Text Size Test")
        }
    }
    Row{
        x:20
        y:150
        spacing: 4*resizeHandler.horizontalRatio
        Button{
            text: "Button1"
        }
        Button{
            text: "Button2"
        }
    }
    ComboBox{
        x:20
        y:200
        model: ["Combobox Test"]
    }

    ListView{
        y:150
        x:250
        width: 100
        height:200
        model: 5
        header:Rectangle{
            height: 20
            Text {
                text: qsTr("ListView Test")
            }
        }

        delegate: Rectangle{
            height: 20
            border.width: 2
            Text {
                text: index
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

原始比例 
横向拉伸 
整体拉伸 
本章节相应的实例代码请查看本人的GitHub


相关文章推荐

编写Qt Designer自定义控件(四)——使用自定义控件

接上文:编写Qt Designer自定义控件(二)——给自定义控件添加属性         控件编写完毕以后,把生成的dll和lib文件一起拷贝到Qt安装目录下的插件目录里,比如我安装在D盘里的Qt...
  • giselite
  • giselite
  • 2013年10月11日 19:47
  • 12782

编写Qt Designer自定义控件(二)——编写自定义控件界面

接上文:编写Qt Designer自定义控件——如何创建并使用Qt自定义控件         既然是控件,就应该有界面,默认生成的控件类只是一个继承了QWidget的类,如下: #ifndef LO...
  • giselite
  • giselite
  • 2013年10月11日 19:39
  • 22500

QT应用程序分辨率自适应

QT应用程序分辨率自适应一、应用程序分辨率自适应    为了满足应用程序能在不同尺寸及分辨率的屏幕下能够正常的运行显示,就需要对不同的分辨率进行自适应,而且应用程序分辨率自适应的问题在应用UI设计布局...

QT应用程序分辨率自适应

QT应用程序分辨率自适应 一、应用程序分辨率自适应     为了满足应用程序能在不同尺寸及分辨率的屏幕下能够正常的运行显示,就需要对不同的分辨率进行自适应,而且应用程序分辨率自适应的问题在...

创建分辨率自适应的Windows Phone 8应用程序

1. 引言     Windows Phone 7平台只支持WVGA分辨率(480*800)的设备,这对于应用程序的UI设计来说是有利的,因为设计人员不用考虑多分辨率对UI控件布局的影响。但是,...

[android UI]应用程序自适应屏幕大小

一:不同的layout Android手机屏幕大小不一,有480x320, 640x360, 800x480.怎样才能让App自动适应不同的屏幕呢?    其实很简单,只需要在res目录下创建不同的l...
  • gyflyx
  • gyflyx
  • 2011年06月21日 17:10
  • 700

Android应用程序自适应屏幕大小的解决办法

android应用自适应多分辨率的解决方法  1. 首先是建立多个layout文件夹(drawable也一样)。 在res目录下建立多个layout文件夹,文件夹名称为layout-800x4...

android 应用程序自适应屏幕大小

android应用自适应多分辨率的解决方法  1. 首先是建立多个layout文件夹(drawable也一样)。 在res目录下建立多个layout文件夹,文件夹名称为layout-800x4...
  • MYBOYER
  • MYBOYER
  • 2013年05月28日 17:05
  • 523

[android UI]应用程序自适应屏幕大小

[android UI]应用程序自适应屏幕大小 AndroidUI游戏XML活动 一:不同的layout Android手机屏幕大小不一,有480x320, 640x360, 80...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:QT应用程序分辨率自适应
举报原因:
原因补充:

(最多只允许输入30个字)