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,只要你提供的图片为透明的,那效果是最优的。