Qt应用

Qt函数

1、resize()函数是用来设置Qt窗体的大小,不能设置Qt窗体的位置;

2、move()函数是用来设置Qt窗体的位置,不能设置Qt窗体的大小。其大小依靠Qt窗体(或者resize()函数)来决定的,其参数只需要左上角的起始点就可以了;

3、setGeometry()函数也是用来设置Qt窗体的位置,不过它与move()函数的不同点是其参数必须是两个点:左上角与右下角(或对应的长度与高度);


Qt无边框窗体拖动大小

具体细节说明可以参考http://www.cnblogs.com/xufeiyang/p/3313104.html和http://blog.csdn.net/kfbyj/article/details/9284923,在参考资料的基础上添加了一些自己的小东西(建议去优化代码,其实里面的很多东西是可以忽略):

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    isLeftPressDown = false;
    this->dir = NONE;
    this->setMinimumSize(100, 150);
    this->setMaximumSize(800, 550);
    this->setWindowFlags(Qt::FramelessWindowHint|Qt::WindowSystemMenuHint );
    this->setMouseTracking(true);
    //this->setStyleSheet("QDialog{background:url(:/bg_main.png)}");
    this->setStyleSheet("QDialog{background:url(../background.bmp)}");
}

Dialog::~Dialog()
{
    delete ui;
}
void Dialog::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton) {
        isLeftPressDown = false;
        if(dir != NONE) {
            this->releaseMouse();
            this->setCursor(QCursor(Qt::ArrowCursor));
        }
    }
}

void Dialog::mousePressEvent(QMouseEvent *event)
{
    switch(event->button()) {
    case Qt::LeftButton:
        isLeftPressDown = true;
        if(dir != NONE) {
            this->mouseGrabber();
        } else {
            dragPosition = event->globalPos() - this->frameGeometry().topLeft();
        }
        break;
    case Qt::RightButton:
        this->close();
        break;
    default:
        QDialog::mousePressEvent(event);
    }
}

void Dialog::mouseDoubleClickEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton)
    {
        if (windowState() != Qt::WindowFullScreen)
            setWindowState(Qt::WindowFullScreen);
        else
            setWindowState(Qt::WindowNoState);
    }

    QDialog::mouseDoubleClickEvent(event);
}

void Dialog::mouseMoveEvent(QMouseEvent *event)
{
    QPoint gloPoint = event->globalPos();
    QRect rect = this->rect();
    QPoint tl = mapToGlobal(rect.topLeft());//左上角的坐标点(相对屏幕的坐标)
    QPoint rb = mapToGlobal(rect.bottomRight());//右上角的坐标点(相对屏幕的坐标)

    if(!isLeftPressDown) {
        this->region(gloPoint);
    } else {

        if(dir != NONE) {
            QRect rMove(tl, rb);

            switch(dir) {
            case LEFT:
                if(rb.x() - gloPoint.x() <= this->minimumWidth() ||
                   rb.x() - gloPoint.x() >= this->maximumWidth())
                    rMove.setX(tl.x());
                else
                    rMove.setX(gloPoint.x());
                break;
            case RIGHT:
                rMove.setWidth(gloPoint.x() - tl.x());
                break;
            case UP:
                if(rb.y() - gloPoint.y() <= this->minimumHeight())
                    rMove.setY(tl.y());
                else
                    rMove.setY(gloPoint.y());
                break;
            case DOWN:
                rMove.setHeight(gloPoint.y() - tl.y());
                break;
            case LEFTTOP:
                if(rb.x() - gloPoint.x() <= this->minimumWidth())
                    rMove.setX(tl.x());
                else
                    rMove.setX(gloPoint.x());
                if(rb.y() - gloPoint.y() <= this->minimumHeight())
                    rMove.setY(tl.y());
                else
                    rMove.setY(gloPoint.y());
                break;
            case RIGHTTOP:
                rMove.setWidth(gloPoint.x() - tl.x());
                rMove.setY(gloPoint.y());
                break;
            case LEFTBOTTOM:
                rMove.setX(gloPoint.x());
                rMove.setHeight(gloPoint.y() - tl.y());
                break;
            case RIGHTBOTTOM:
                rMove.setWidth(gloPoint.x() - tl.x());
                rMove.setHeight(gloPoint.y() - tl.y());
                break;
            default:

                break;
            }
            this->setGeometry(rMove);
        } else {
            move(event->globalPos() - dragPosition);
            event->accept();
        }
    }
    QDialog::mouseMoveEvent(event);
}

void Dialog::region(const QPoint &cursorGlobalPoint)
{
    QRect rect = this->rect();
    QPoint tl = mapToGlobal(rect.topLeft());
    QPoint rb = mapToGlobal(rect.bottomRight());
    int x = cursorGlobalPoint.x();
    int y = cursorGlobalPoint.y();

    if(tl.x() + PADDING >= x && tl.x() <= x && tl.y() + PADDING >= y && tl.y() <= y) {
        // 左上角
        dir = LEFTTOP;
        this->setCursor(QCursor(Qt::SizeFDiagCursor));
    } else if(x >= rb.x() - PADDING && x <= rb.x() && y >= rb.y() - PADDING && y <= rb.y()) {
        // 右下角
        dir = RIGHTBOTTOM;
        this->setCursor(QCursor(Qt::SizeFDiagCursor));
    } else if(x <= tl.x() + PADDING && x >= tl.x() && y >= rb.y() - PADDING && y <= rb.y()) {
        //左下角
        dir = LEFTBOTTOM;
        this->setCursor(QCursor(Qt::SizeBDiagCursor));
    } else if(x <= rb.x() && x >= rb.x() - PADDING && y >= tl.y() && y <= tl.y() + PADDING) {
        // 右上角
        dir = RIGHTTOP;
        this->setCursor(QCursor(Qt::SizeBDiagCursor));
    } else if(x <= tl.x() + PADDING && x >= tl.x()) {
        // 左边
        dir = LEFT;
        this->setCursor(QCursor(Qt::SizeHorCursor));
    } else if( x <= rb.x() && x >= rb.x() - PADDING) {
        // 右边
        dir = RIGHT;
        this->setCursor(QCursor(Qt::SizeHorCursor));
    }else if(y >= tl.y() && y <= tl.y() + PADDING){
        // 上边
        dir = UP;
        this->setCursor(QCursor(Qt::SizeVerCursor));
    } else if(y <= rb.y() && y >= rb.y() - PADDING) {
        // 下边
        dir = DOWN;
        this->setCursor(QCursor(Qt::SizeVerCursor));
    }else {
        // 默认
        dir = NONE;
        this->setCursor(QCursor(Qt::ArrowCursor));
    }
}
Qt圆角窗体(带透明)的实现有四种:

1、在构造函数中添加如下代码

setWindowFlags(Qt::FramelessWindowHint);
setAttribute(Qt::WA_TranslucentBackground);
说明:第一句表示窗体是无边框的;第二句使窗体的背景为透明;此时直接运行,看不到任何东西。


还要在paintEvent(QMouseEvent *event)再次添加如下代码

QPainter painter(this);
//painter.fillRect(rect(),QColor(255,255,255,100));
QPixmap pixmap("../login1.png");
painter.drawPixmap(pixmap.rect(), pixmap);
说明:第一句声明一个QPainter对象;第二句为注释,如果没有图片,直接用颜色填充可以看到透明度为100的窗体;第三句声明一个QPixmap对象,参数是一个图片的路径;第四句把图片绘制到窗体上。


2、在构造函数中添加如下代码

setWindowFlags(Qt::FramelessWindowHint);
重载paintEvent并添加如下代码

QBitmap bmp(this->size());
bmp.fill();
QPainter p(&bmp);
p.setPen(Qt::NoPen);
p.setBrush(Qt::black);
p.setRenderHint(QPainter::Antialiasing);
p.drawRoundedRect(bmp.rect(),10,10);
setMask(bmp);//设置窗体遮罩

3、在构造函数中添加如下代码

setWindowFlags(Qt::FramelessWindowHint);

重载paintEvent并添加如下代码

    QBitmap bmp(this->size());
    bmp.fill();
    QPainter p(&bmp);
    p.setRenderHint(QPainter::Antialiasing);
    //只要上边角圆弧
    int arcR = 20;
    QRect rect = this->rect();
    QPainterPath path;
    //逆时针
    path.moveTo(arcR, 0);
    path.arcTo(0, 0, arcR * 2, arcR * 2, 90.0f, 90.0f);
    path.lineTo(0, rect.height());
    path.lineTo(rect.width(), rect.height());
    path.lineTo(rect.width(), arcR);
    path.arcTo(rect.width() - arcR * 2, 0, arcR * 2, arcR * 2, 0.0f, 90.0f);
    path.lineTo(arcR, 0);
    p.drawPath(path);
    p.fillPath(path, QBrush(Qt::Red)); //arm和windows平台没有这行代码将显示一个透明的空空的框
    setMask(bmp);
其中使用QPainterPath中的moveTo等函数可以使用QPainter中的函数替换。


方法2跟方法3都是采用遮罩的方式,本章推荐使用方法1,只要你提供的图片为透明的,那效果是最优的。







你可能感兴趣的:(Qt,Qt,Qt圆角窗体,Qt无边框窗体拖动,Qt窗体透明)