Qt 어플리케이션 해상도 맞춤형(글꼴, 컨트롤 변경 내용 적용)(전재)

7715 단어 Qt
Qt에서 모든 컴퓨터의 해상도가 다르다. 예를 들어 당신의 해상도가 1920*1080이면 800*480에 컨트롤러가 완전하게 표시되지 않기 때문에 우리는 컨트롤러가 변화를 따라야 한다.
내가 사용하는 방법은 비교적 형편없고Qt는 잘 쓰지 못한다
레이아웃 레이아웃을 통해 창의 해상도에 적응하려면 레이아웃 레이아웃에 적응하는 컨트롤을 추가해야 합니다. 레이아웃의 부모 대상의 사이즈가 변할 때 레이아웃은 부모 대상의 변화 폭과 비례에 따라 레이아웃의 컨트롤을 축소하여 해당 컨트롤의 해상도에 적응하도록 합니다. 
그러나 QtCreator Designer에 추가된layout에 문제가 있습니다. 다음 그림은 Designer에 Vertical Layout을 추가하고layout에 두 개의 PushButton을 추가합니다. 프로그램을 실행한 후에 프로그램 크기를 조정하면 중간의 PushButton은 창 크기에 따라 축소되지 않습니다.
이것은 리소스 이벤트에서 ui->vertical LayoutWidget를 확장하지 않았기 때문에 리소스 이벤트의 함수를 다시 써야 합니다.
void MainWindow::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event);
    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();
    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);
}

레이아웃을 이용하여 컨트롤러의 레이아웃 축소를 하는 것은 간단하고 내부 세부 사항에 주목할 필요가 없다. 그러나 레이아웃을 이용하여 레이아웃을 할 때 컨트롤러의 위치와 크기는 레이아웃의 제약을 받아 크기와 위치를 정확하게 제어할 수 없다. 인터페이스의 복잡한 레이아웃 요구에 대해 레이아웃은 사용 요구를 만족시키지 못한다. 이 부분의 컨트롤러는 컨트롤러의 축소만 사용자 정의할 수 있고 프로그램 창의 축소는 해상도에 적응하는 것이다.
구체적인 축소 규칙은 앞과 유사하다. 프로그램 창의 사이즈가 변할 때 프로그램 창의 축소 비율인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 m_resizeMap;

그리고 검색 창의 모든 QWidget 대상을 찾습니다. 이 대상을 찾으려면 스스로 제어해야 합니다. 블로그에 불완전하게 표시되고 초기 위치를 기록해야 합니다.
m_autoResizeHandler->setAutoResizeFlag(
            AutoResize::INCLUDE_BUTTON|AutoResize::INCLUDE_COMBOBOX|
            AutoResize::INCLUDE_EDITOR|AutoResize::INCLUDE_LABEL
            );
QWidget *item=NULL;
AutoResizeOriginalData resizeData;
QRect tmp;
QList _labelList=m_autoResizeObj->findChildren();
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;
}
QList _buttonList=m_autoResizeObj->findChildren();
for(auto it=_buttonList.begin();it!=_buttonList.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;
}

창 객체의 resize Event 함수를 다시 로드하여 각 컨트롤에 맞게 조정
m_horRatio=this->rect().width()/m_baseWidth;
m_verRatio=this->rect().height()/m_baseHeight;
QMapIterator _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);
        }

주의: 인터페이스에 일부 컨트롤이layout에 포함되면 QWidget 대상을 찾을 때 이 부분 컨트롤도 포함됩니다. 그러면 사이즈 축소를 할 때 레이아웃이 서로 영향을 주어 인터페이스가 잘못된 위치를 초래합니다. 이 컨트롤을 제거하고layout에 넘겨 축소를 제어해야 합니다. 구체적인 동작은 다음과 같습니다. 모든 하위 대상을 제거하는 함수를 정의합니다.
void AutoResize::ignoreAllChiledren(QObject* obj)
{
    QList children=obj->children();
    for(auto it=children.begin();it!=children.end();it++)
    {
        QWidget *item=qobject_cast(*it);
        m_ignoreItem.push_back(item);
        AutoResizeOriginalData resizeData;
        if(!item)
            continue;
        m_resizeMap.remove(item);
    }
}
 layout:
QString desName="widget";
QList layoutList=m_autoResizeObj->findChildren();
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((*it)->parent());
        ignoreAllChiledren(layoutWidget);
    }
}

\글꼴 배율 조정
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 _labelList=m_autoResizeObj->findChildren();
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;
    }
}
// 
void AutoResize::calculateResizeRatio()
{
    m_horRatio=m_autoResizeObj->width()/m_baseWidth;
    m_verRatio=m_autoResizeObj->height()/m_baseHeight;
    m_fontRatio=m_horRatio _fontIt(m_fontMap);
        while(_fontIt.hasNext())
        {
            _fontIt.next();
            QWidget* _item=_fontIt.key();
              changedFont=_fontIt.value().data_font;
              fontAutoResize(_item,changedFont.pointSize());
        }
    }
}

여기에서 원문을 완성했다.https://blog.csdn.net/matengxiao/article/details/52853332그에게도 코드 다운로드가 있다

좋은 웹페이지 즐겨찾기