QWidget类是所有可视控件的基类,控件是用户界面的最小元素,用于接受各种事件(如:鼠标、键盘等)并且绘制出来给用户观看。每个控件都是矩形的,他们按照Z轴顺序排列。如果控件没有父控件,则称之为窗口,窗口会被一个框架包裹(包含标题栏,边框等),可以通过某些函数来修改边框属性。
QWidget的大小和位置
获取QWidget的大小和位置
#include <QApplication>
#include <QWidget>
#include <QDebug>
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QWidget w; // 创建窗口
w.show(); // 显示窗口
//获取窗口大小与位置
qInfo() << w.pos() << w.x() << w.y();
qInfo() << w.size() << w.width() << w.height();
//获取窗口几何
qInfo() << w.geometry() << w.frameGeometry(); // 不带边框与带边框
qInfo() << w.frameSize(); // 带边框的大小
qInfo() << w.rect(); // 内部矩形(客户区)大小
return a.exec();
}
第一行输出指的是窗口的全局坐标
第二行输出指的是客户区的大小(不包括边框)
第三行输出的是窗口客户区的全局坐标和大小(前者不带边框,后者带边框)
第四行输出的是带边框的窗口的大小
第五行输出的是窗口客户区相对于窗口的坐标以及客户区大小(不带边框)
设置QWidget的大小和位置
//移动窗口的位置(包括边框)
void move(const QPoint &)
void move(int x, int y)
//设置窗口的大小(不包括边框)
void resize(int w, int h)
void resize(const QSize &)
//设置窗口的大小和位置 (不包括边框,以客户区坐标为准)
void setGeometry(const QRect &)
void setGeometry(int x, int y, int w, int h)
设置窗口固定大小
//不包括边框,设置的是客户区大小且不可拖动缩放窗口大小
void setFixedSize(const QSize &s)
void setFixedSize(int w, int h)
限定窗口的大小
//限定窗口的最大大小(不包括边框)
void setMaximumWidth(int maxw)
void setMaximumHeight(int maxh)
void setMaximumSize(const QSize &)
void setMaximumSize(int maxw, int maxh)
//限定窗口的最小大小(不包括边框)
void setMinimumWidth(int minw)
void setMinimumHeight(int minh)
void setMinimumSize(const QSize &)
void setMinimumSize(int minw, int minh)
坐标系统转换
QPoint mapFrom(const QWidget *parent, const QPoint &pos) const
QPoint mapFromGlobal(const QPoint &pos) const
QPoint mapFromParent(const QPoint &pos) const
QPoint mapTo(const QWidget *parent, const QPoint &pos) const
QPoint mapToGlobal(const QPoint &pos) const
QPoint mapToParent(const QPoint &pos) const
这几个函数都是转换相对坐标系用的. 用另一个坐标系统的坐标值, 来表达当前坐标系统中某个坐标所指向的某个点,
相对坐标:获取自己相对于父控件的位置 QWidget::pos()
绝对坐标:将当前控件的相对位置转换为屏幕绝对位置 QWidget::mapToGlobal()
绝对坐标转为相对坐标:将屏幕绝对位置对应到控件的相对位置 QWidget::mapFromGlobal()
#include <QApplication>
#include <QWidget>
#include <QDebug>
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QWidget w; // 创建窗口
w.resize(640, 480);
auto w1 = new QWidget(&w);
w1->setGeometry(100, 100, 100, 100);
w1->setStyleSheet("background-color:red"); // 设置w1背景色为red
auto w2 = new QWidget(w1);
w2->setGeometry(20, 20, 60, 60);
w2->setStyleSheet("background-color:deepskyblue");
w.show(); // 显示窗口
//1. 求w1的50,50位置在父控件上的坐标
qInfo() << w1->mapToParent(QPoint(50, 50)); // 150,150
//2. 求w的120,120在子控件w1上面的坐标
qInfo() << w1->mapFromParent(QPoint(120, 120)); // 20,20
//3. 求w2的0,0位置在w上的坐标
qInfo() << w2->mapTo(&w, QPoint(0, 0)); // 120,120
//4. 求w上的130,130在w2上的坐标
qInfo() << w2->mapFrom(&w, QPoint(130, 130)); // 10,10
//5. 求全局坐标500,286在w上的坐标
qInfo() << w.mapFromGlobal(QPoint(500, 286)); // 100,100
//6. 求w的0,0位置的全局坐标
qInfo() << w.mapToGlobal(QPoint(0, 0)); // 400,186
return a.exec();
}
内容边距
设置小部件内容周围的空白,使其具有左、上、右和下的大小。边距被布局系统使用,并且可以被子类用来指定要绘制的区域。
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QWidget w; // 创建窗口
w.resize(640, 480);
//原来的效果
auto label = new QLabel("人狠话不多", &w);
label->resize(200, 200);
label->setStyleSheet("background-color:green");
//设置内容边距后的效果
auto label2 = new QLabel("人狠话不多", &w);
label2->move(label->x() + label->width(), 0);
label2->resize(200, 200);
label2->setStyleSheet("background-color:deepskyblue");
label2->setContentsMargins(120, 150, 0, 0);
w.show(); // 显示窗口
qInfo() << label2->contentsRect() // 去掉外边距的内容矩形
<< label2->contentsMargins(); // 内容边距
return a.exec();
}
鼠标指针
鼠标指针的形状
如果要全局设置鼠标光标样式,可以使用
QGuiApplication::setOverrideCursor()
, 设置鼠标指针的形状需要使用QCursor类,通过像素图或枚举指定鼠标光标形状。
QCursor cursor() const
void setCursor(const QCursor &)
void unsetCursor()
Qt中自带的鼠标指针形状在枚举Qt::CursorShape中
直接使用setCursor()函数设置即可
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QWidget w; // 创建窗口
w.resize(640, 480);
w.setCursor(QCursor(Qt::PointingHandCursor)); // 设置光标样式
w.show(); // 显示窗口
return a.exec();
}
点击按钮切换光标样式的案例
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QWidget w; // 创建窗口
w.resize(640, 480);
auto btn = new QPushButton("切换光标样式", &w);
QObject::connect(btn, &QPushButton::clicked, [&]()
{
static int i = 0;
w.setCursor(QCursor(Qt::CursorShape(i)));
i = (i + 1) % 22;
});
w.show(); // 显示窗口
return a.exec();
}
自定义光标的使用
QCursor(const QPixmap &pixmap, int hotX = -1, int hotY = -1)
QCursor(const QBitmap &bitmap, const QBitmap &mask, int hotX = -1, int hotY = -1)
QCursor(Qt::CursorShape shape)
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QWidget w; // 创建窗口
w.resize(640, 480);
auto btn = new QPushButton("Button", &w);
QPixmap map = QPixmap("cursor.png");
map = map.scaled(30, 30); // 将图片缩放到(30,30)大小
w.setCursor(QCursor(map, 0, 0)); // 0,0表示将焦点放到图片(0,0)的位置
w.show(); // 显示窗口
return a.exec();
}
可能会出现的error:
QPixmap::scaled: Pixmap is a null pixmap
QCursor: Cannot create bitmap cursor; invalid bitmap(s)
这是因为图片没有在指定路径下找到,将图片放到项目的Debug目录下与exe文件同级目录即可。
获取和设置光标的坐标
[static] QPoint pos()
[static] QPoint pos(const QScreen *screen)
[static] void setPos(int x, int y)
[static] void setPos(QScreen *screen, int x, int y)
[static] void setPos(const QPoint &p)
[static] void setPos(QScreen *screen, const QPoint &p)
qInfo() << QCursor::pos(); // 获取光标的全局坐标
QCursor::setPos(0, 0); // 将光标设置到全局(0,0)的位置