加载中…
个人资料
一去二三里
一去二三里
  • 博客等级:
  • 博客积分:0
  • 博客访问:2,322,840
  • 关注人气:898
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

Qt之窗体拖拽、自适应分辨率、自适应大小

(2015-04-22 11:47:45)
标签:

qt

paintevent

nativeevent

qt自适应

qt绘制背景

分类: Qt
    在自定义无边框、标题栏的界面中,需要自己实现最小化、最大化、关闭、窗体背景等功能。最小化、最大化、关闭等按钮设计及功能比较简单,这里就不多做介绍。今天主要介绍一下绘制背景的问题,主要实现自适应屏幕分辨率。
    先看一下UI设计的图(大小:1298*786):
Qt之窗体拖拽、自适应分辨率、自适应大小
    如果软件没有最大化、拖拽大小功能,那么最简单不过了,直接绘制背景就OK了,但是为了易用性,这些功能都是必不可少的。

    如何自适应屏幕分辨率呢?
  • 1、为每个分辨率单独做一张图
  • 2、将图片切分为九宫格形
  • 3、在原图基础上进行实现
    当然,这里是我能想到的一些方案,也许还有更多的其它方案。。。
  • 方案一:常用的分辨率很多,800*600、1024*768、1280*800、1680*1050等等。。。那么得需要多少张图呢?
  • 方案二:需要将图片切分,而且如果切分不合适,还得来回重复切图,加大UI工作量。。。
  • 方案三:在原图的基础上实现,在代码逻辑上处理!
    综上所述:听起来方案三是比较好,那么如何实现呢?请看过来!

    因为界面存在缩放,所以如果窗体有圆角、或者存在阴影效果,缩放过程中会变形,所以需要进行处理!
思路:
  • 1、左上角、左下角、右上角、右下角进行切分分别绘制(下面所说的切分都使用代码实现)
  • 2、左、上、右、下部位进行切分,计算出窗体的大小后,在原方向进行拉伸
  • 3、中央部分切分出一部分进行平铺
  • 4、让UI将圆角及阴影部分标注出来,这里需要标注宽和高,以便于实现切图
    现在,来开始我们的代码之旅吧!

绘制背景:

void paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    QPixmap background(":/background");

    int nLeftWidth = 144;
    int nBottomHeight = 24;
    int nTopHeight = 67;

    QRect left(0, 100, nLeftWidth, 100);
    QRect right(background.width() - nLeftWidth, 100, nLeftWidth, 100);
    QRect leftTop(0, 0, nLeftWidth, nTopHeight);
    QRect rightTop(background.width() - nLeftWidth, 0, nLeftWidth, nTopHeight);
    QRect top(150, 0, 150, nTopHeight);
    QRect leftBottom(0, background.height() - nBottomHeight, nLeftWidth, nBottomHeight);
    QRect rightBottom(background.width() - nLeftWidth, background.height() - nBottomHeight, nLeftWidth, nBottomHeight);
    QRect bottom(150, background.height() - nBottomHeight, 100, nBottomHeight);
    QRect center(300, 300, 100, 100);

    QRect leftRect(0, nTopHeight, nLeftWidth, this->height() - nTopHeight - nBottomHeight);
    QRect rightRect(this->width() - nLeftWidth, nTopHeight, nLeftWidth, this->height() - nTopHeight - nBottomHeight);
    QRect leftTopRect(0, 0, nLeftWidth, nTopHeight);
    QRect rightTopRect(this->width() - nLeftWidth, 0, nLeftWidth, nTopHeight);
    QRect topRect(nLeftWidth, 0, this->width() - nLeftWidth*2, nTopHeight);
    QRect leftBottomRect(0, this->height() - nBottomHeight, nLeftWidth, nBottomHeight);
    QRect righttBottomRect(this->width() - nLeftWidth, this->height() - nBottomHeight, nLeftWidth, nBottomHeight);
    QRect bottomRect(nLeftWidth, this->height() - nBottomHeight, this->width() - nLeftWidth*2, nBottomHeight);
    QRect centerRect(nLeftWidth, nTopHeight, this->width() - nLeftWidth*2, this->height() - nTopHeight - nBottomHeight);

    painter.drawPixmap(topRect, background, top);
    painter.drawPixmap(leftRect, background, left);
    painter.drawPixmap(rightRect, background, right);
    painter.drawPixmap(rightTopRect, background, rightTop);
    painter.drawPixmap(leftTopRect, background, leftTop);
    painter.drawPixmap(leftBottomRect, background, leftBottom);
    painter.drawPixmap(righttBottomRect, background, rightBottom);
    painter.drawPixmap(bottomRect, background, bottom);
    painter.drawPixmap(centerRect, background, center);
}
控制窗体拖拽进行缩放:

bool nativeEvent(const QByteArray &eventType, void *message, long *result)
{
    Q_UNUSED(eventType)

    MSG *param = static_cast(message);
    switch (param->message)
    {
    case WM_NCHITTEST:
    {
        int nX = GET_X_LPARAM(param->lParam) - this->geometry().x();
        int nY = GET_Y_LPARAM(param->lParam) - this->geometry().y();

        //指定标题栏区域
        if (this->childAt(nX, nY))
        {
            return false;
        }
        else
        {
            *result = HTCAPTION;
        }

        if ((nX > 0) && (nX < m_shadowSize))
            *result = HTLEFT;
        if ((nX > this->width() - m_shadowSize) && (nX < this->width()))
            *result = HTRIGHT;
        if ((nY > 0) && (nY < m_shadowSize))
            *result = HTTOP;
        if ((nY > this->height() - m_shadowSize) && (nY < this->height()))
            *result = HTBOTTOM;
        if ((nX > 0) && (nX < m_shadowSize) && (nY > 0)
                && (nY < m_shadowSize))
            *result = HTTOPLEFT;
        if ((nX > this->width() - m_shadowSize) && (nX < this->width())
                && (nY > 0) && (nY < m_shadowSize))
            *result = HTTOPRIGHT;
        if ((nX > 0) && (nX < m_shadowSize)
                && (nY > this->height() - m_shadowSize) && (nY < this->height()))
            *result = HTBOTTOMLEFT;
        if ((nX > this->width() - m_shadowSize) && (nX < this->width())
                && (nY > this->height() - m_shadowSize) && (nY < this->height()))
            *result = HTBOTTOMRIGHT;

        m_maximize = this->isMaximize();
        return true;
    }
    }

    return QWidget::nativeEvent(eventType, message, result);
}
    到这里,我们就完成了背景自适应分辨率、拖拽功能。。。如果对窗口进行其它功能完善,比如:双击标题栏最大化/还原,实现窗体拖动等,则需要处理相应的事件即可!


注:
    技术在于交流、沟通,转载请注明出处并保持作品的完整性。

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有