控件坐标位置自适应算法

本文介绍了一种控件坐标位置自适应算法,以解决窗口大小变化时,背景图片和控件位置的问题。通过计算窗口与背景图片的偏移量,保持控件在背景图片上的相对位置不变,实现窗口缩放时控件的自动定位。代码示例展示了在Qt中如何实现这一功能。

按照俺以前的做法是在gimp中算好背景图片资源的坐标及尺寸,但是这样做也不好,针对窗口的不同大小,不同的分辨率,控件就偏多很历害。

但是如果限制窗口不能调节大小,也不好,毕竟在大分辨率的屏幕屏上,客户会不满意的。

由于俺使用的是png图片,不是svg,所以放大会有失帧现在,所以俺不让它放大。

只是如果窗口大了的话,就居中显示,以前该背景图片上的所有的控件坐标都是绝对坐标,所以当窗口改变时,计算好坐标再绘制背景图片,计算方法如下:

x= (window width - background image width) /2

y=(window height - background image height) /2

这样就相当于改变了绘制背景图像时的左上角坐标,但是图像尺寸还是按照以前的,不缩放。

以前的控件坐标是绝对于背景图片的,所以现在是背景图片偏移了坐标,

故对于控件的定位可以在resizeEvent()事件中,对控件坐标重新定位即可。

它的最新的绝对坐标计算方法是

绝对坐标+偏移量。

偏移量应该使用背景图片的偏移量。

若以前为

this->m_lineEditOut->setGeometry(62,81,31,10);

则现在应该变为

    qint32 tOffsetX=(this->size().width()-this->m_backgroundPixmap.width())/2;
    qint32 tOffsetY=(this->size().height()-this->m_backgroundPixmap.height())/2;
    this->m_lineEditOut->setGeometry(62+tOffsetX,81+tOffsetY,31,10);

以下为试验的效果图:

可以看到,不管窗口如何缩放,那显示数字的4个文本框都是那么听话的被放置的合适的位置上。

老规矩,贡献出代码:

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPaintEvent>
#include <QLineEdit>
#include <QTimer>
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();
protected:
   void paintEvent(QPaintEvent *event);
   void resizeEvent(QResizeEvent *event);
private slots:
   void updateTemperature();
private:
   QLineEdit *m_lineEditOut;
   QLineEdit *m_lineEditIn;
   QLineEdit *m_lineEditMix;
   QLineEdit *m_lineEditCheck;
   QTimer *m_timer;

   QPixmap m_backgroundPixmap;
};

#endif // WIDGET_H

#include "widget.h"
#include <QPaintEvent>
#include <QPainter>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    QFont tFont=this->font();
    tFont.setPixelSize(10);
    this->setFont(tFont);

    this->m_backgroundPixmap.load(":/background.png");
    this->m_lineEditOut=new QLineEdit(this);
    this->m_lineEditOut->setGeometry(62,81,31,10);
    this->m_lineEditOut->setAlignment(Qt::AlignCenter);
    this->m_lineEditOut->setStyleSheet(QString("QLineEdit{border:0px}"));
    this->m_lineEditIn=new QLineEdit(this);
    this->m_lineEditIn->setGeometry(222,81,31,10);
    this->m_lineEditIn->setAlignment(Qt::AlignCenter);
    this->m_lineEditIn->setStyleSheet(QString("QLineEdit{border:0px}"));
    this->m_lineEditMix=new QLineEdit(this);
    this->m_lineEditMix->setGeometry(142,234,31,10);
    this->m_lineEditMix->setAlignment(Qt::AlignCenter);
    this->m_lineEditMix->setStyleSheet(QString("QLineEdit{border:0px}"));
    this->m_lineEditCheck=new QLineEdit(this);
    this->m_lineEditCheck->setGeometry(36,319,31,10);
    this->m_lineEditCheck->setAlignment(Qt::AlignCenter);
    this->m_lineEditCheck->setStyleSheet(QString("QLineEdit{border:0px}"));

    this->m_timer=new QTimer;
    this->m_timer->setInterval(500);
    connect(this->m_timer,SIGNAL(timeout()),this,SLOT(updateTemperature()));
    this->m_timer->start();
}
Widget::~Widget()
{
    delete this->m_lineEditIn;
    delete this->m_lineEditOut;
    delete this->m_lineEditMix;
    delete this->m_lineEditCheck;
    delete this->m_timer;
}
void Widget::paintEvent(QPaintEvent *event)
{
    QPainter tPainter(this);
    QRect tBack(0,0,this->size().width(),this->size().height());
    tPainter.fillRect(tBack,Qt::white);
    qint32 tX=(this->size().width()-this->m_backgroundPixmap.width())/2;
    qint32 tY=(this->size().height()-this->m_backgroundPixmap.height())/2;
    tPainter.drawPixmap(tX,tY,this->m_backgroundPixmap.width(),this->m_backgroundPixmap.height(),this->m_backgroundPixmap);
}
void Widget::resizeEvent(QResizeEvent *event)
{
    qint32 tOffsetX=(this->size().width()-this->m_backgroundPixmap.width())/2;
    qint32 tOffsetY=(this->size().height()-this->m_backgroundPixmap.height())/2;
    this->m_lineEditOut->setGeometry(62+tOffsetX,81+tOffsetY,31,10);
    this->m_lineEditIn->setGeometry(222+tOffsetX,81+tOffsetY,31,10);
    this->m_lineEditMix->setGeometry(142+tOffsetX,234+tOffsetY,31,10);
    this->m_lineEditCheck->setGeometry(36+tOffsetX,319+tOffsetY,31,10);
}
void Widget::updateTemperature()
{
    qsrand(time(NULL));
    int nOut = qrand()%20;
    int nIn = qrand()%20;
    int nMix = qrand()%20;
    int nCheck = qrand()%100;
    this->m_lineEditOut->setText(QString("%1").arg(nOut));
    this->m_lineEditIn->setText(QString("%1").arg(nIn));
    this->m_lineEditMix->setText(QString("%1").arg(nMix));
    this->m_lineEditCheck->setText(QString("%1").arg(nCheck));
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值