Qt提供了很多关于获取窗体位置及显示区域大小的函数,统称为“位置函数”或“位置相关函数”。
实例试验各个位置函数效果:
geometry.h:
#include
#include
#include
class Geomtry : public QDialog
{
Q_OBJECT
public:
Geomtry(QWidget *parent = 0);
~Geomtry();
void updateLabel();
private:
QLabel *xLabel;
QLabel *xValueLabel;
QLabel *yLabel;
QLabel *yValueLabel;
QLabel *frmLabel;
QLabel *frmValueLabel;
QLabel *posLabel;
QLabel *posValueLabel;
QLabel *geoLabel;
QLabel *geoValueLabel;
QLabel *widthLabel;
QLabel *widthValueLabel;
QLabel *heightLabel;
QLabel *heightValudeLabel;
QLabel *rectLabel;
QLabel *rectValueLabel;
QLabel *sizeLabel;
QLabel *sizeValudeLabel;
QGridLayout *mainLayout;
protected:
void moveEvent(QMoveEvent *);
void resizeEvent(QResizeEvent *);
};
geometry.cpp:
#include "geomtry.h"
Geomtry::Geomtry(QWidget *parent)
: QDialog(parent)
{
xLabel = new QLabel(tr("x():"));
xValueLabel = new QLabel;
yLabel = new QLabel(tr("y():"));
yValueLabel = new QLabel;
frmLabel = new QLabel(tr("y():"));
frmValueLabel = new QLabel;
posLabel = new QLabel(tr("pos():"));
posValueLabel = new QLabel;
geoLabel = new QLabel(tr("geomtry():"));
geoValueLabel = new QLabel;
widthLabel = new QLabel(tr("width():"));
widthValueLabel = new QLabel;
heightLabel = new QLabel(tr("height():"));
heightValudeLabel = new QLabel;
rectLabel = new QLabel(tr("rect():"));
rectValueLabel = new QLabel;
sizeLabel = new QLabel(tr("size():"));
sizeValudeLabel = new QLabel;
mainLayout = new QGridLayout(this);
mainLayout->addWidget(xLabel, 0, 0);
mainLayout->addWidget(xValueLabel, 0, 1);
mainLayout->addWidget(yLabel, 1, 0);
mainLayout->addWidget(yValueLabel, 1, 1);
mainLayout->addWidget(frmLabel, 2, 0);
mainLayout->addWidget(frmValueLabel, 2, 1);
mainLayout->addWidget(posLabel, 3, 0);
mainLayout->addWidget(posValueLabel, 3, 1);
mainLayout->addWidget(geoLabel, 4, 0);
mainLayout->addWidget(geoValueLabel, 4, 1);
mainLayout->addWidget(widthLabel, 5, 0);
mainLayout->addWidget(widthValueLabel, 5, 1);
mainLayout->addWidget(heightLabel, 6, 0);
mainLayout->addWidget(heightValudeLabel, 6, 1);
mainLayout->addWidget(rectLabel, 7, 0);
mainLayout->addWidget(rectValueLabel, 7, 1);
mainLayout->addWidget(sizeLabel, 8, 0);
mainLayout->addWidget(sizeValudeLabel, 8, 1);
updateLabel();
}
Geomtry::~Geomtry()
{
}
// 实现实时更新位置数据
void Geomtry::updateLabel()
{
QString xStr;
xValueLabel->setText(xStr.setNum(x()));
QString yStr;
yValueLabel->setText(yStr.setNum(y()));
// 获得frameGeometry()函数的结果并显示
QString frameStr;
QString frameStr1, frameStr2, frameStr3, frameStr4;
frameStr = frameStr1.setNum(frameGeometry().x()) + "," +
frameStr2.setNum(frameGeometry().y()) + "," +
frameStr3.setNum(frameGeometry().width()) + "," +
frameStr4.setNum(frameGeometry().height());
frmValueLabel->setText(frameStr);
QString posStr;
QString posStr1, posStr2;
posStr = posStr1.setNum(pos().x()) + posStr2.setNum(pos().y());
posValueLabel->setText(posStr);
QString geoStr;
QString geoStr1, geoStr2, geoStr3, geoStr4;
geoStr = geoStr1.setNum(geometry().x()) + "," +
geoStr2.setNum(geometry().y()) + "," +
geoStr3.setNum(geometry().width()) + "," +
geoStr4.setNum(geometry().height());
geoValueLabel->setText(geoStr);
QString wStr, hStr;
widthValueLabel->setText(wStr.setNum(width()));
heightValudeLabel->setText(hStr.setNum(height()));
QString rectStr;
QString rectStr1, rectStr2, rectStr3, rectStr4;
rectStr = rectStr1.setNum(rect().x()) + "," +
rectStr2.setNum(rect().y()) + "," +
rectStr3.setNum(rect().width()) + "," +
rectStr4.setNum(rect().height());
rectValueLabel->setText(rectStr);
QString sizeStr;
QString sizeStr1, sizeStr2;
sizeStr = sizeStr1.setNum(size().width()) + "," + sizeStr2.setNum(size().height());
sizeValudeLabel->setText(sizeStr);
}
// 重定义QWidget的moveEvent函数,响应对话框移动事件
void Geomtry::moveEvent(QMoveEvent *)
{
updateLabel();
}
// 重定义QWidget的resizeEvent函数,响应对话框大小调整事件
void Geomtry::resizeEvent(QResizeEvent *)
{
updateLabel();
}
SVG的英文全称是Scalabe Vector Graphics,即可缩放的矢量图形。它是由万维网联盟制定的一种新的二维矢量图形格式,是一个开放的图形标准。
SVG格式相对于GIF、JPEG格式的优势是:SVG是一种矢量图形格式,相比较来说文件较小,网络传输速度快;可任意缩放而不会破坏图像的清晰度和细节;图像中的文字独立于图像,文字保留可编辑和可搜寻状态,也没有字体的限制。
Qt为SVG格式的图形显示与生成提供了专门的QtSvg模块,此模块包含了与SVG图形相关的所有类,主要有QSvgWidget、QSvgRender、QGraphicsSvgItem
。
使用SVG模块,要在工程文件.pro中加入一行代码:Qt += svg
,然后在头文件中包含相应的库:#include
实例使用Qt的SVG模块实现一个现实SVG功能的窗口,可以对SVG模块进行放大与缩小。
首先在项目中添加一个类用于显示SVG图片,类名为:SvgWidget
// svgwidget主要用于显示SVG图片
#include
#include
#include
#include
class SvgWidget : public QSvgWidget
{
Q_OBJECT
public:
SvgWidget(QWidget *parent = 0);
// 响应鼠标滚轮事件,使SVG图片能够通过鼠标滚轮的滚动改变图片大小
void wheelEvent(QWheelEvent *);
private:
// 用于图片显示尺寸的确定
QSvgRenderer *render;
};
SvgWidget::SvgWidget(QWidget *parent) : QSvgWidget(parent)
{
// 构造函数获得本窗体的QSvgRenderer对象
render = renderer();
}
void SvgWidget::wheelEvent(QWheelEvent *event)
{
// 定义一个值,表示每次滚轮滚动的值,图片大小改变的比例
const double diff = 0.1;
// 先获取图片显示区的大小,以便进行下一步操作
QSize size = render->defaultSize();
int width = size.width();
int height = size.height();
// delta()函数获得滚轮滚动的距离值,返回值大于零是向前滚动
if (event->delta() > 0)
{
width = int(this->width() + this->width() * diff);
height = int(this->height() + this->height() * diff);
}
else
{
width = int(this->width() - this->width() * diff);
height = int(this->height() - this->height() * diff);
}
resize(width, height);
}
然后在创建一个滑动区域类SvgWindow
用于放置变换大小的图片:
#include
#include "svgwidget.h"
// QScrollArea 是一个滚动区域,当图片放大超过主窗口的尺寸时,通过拖曳滚动条方式进行查看
class SvgWindow : public QScrollArea
{
Q_OBJECT
public:
SvgWindow(QWidget *parent = 0);
void setFile(QString);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
private:
SvgWidget *svgWidget;
QPoint mousePressPos;
QPoint scrollBarValueOnMousePress;
};
SvgWindow::SvgWindow(QWidget *parent)
: QScrollArea(parent)
{
svgWidget = new SvgWidget;
setWidget(svgWidget);
}
// 当主窗口中对文件进行了选择和修改时,将调用setFile()函数设置新的文件
void SvgWindow::setFile(QString fileName)
{
if (fileName == "")
return;
svgWidget->load(fileName);
QSvgRenderer *render = svgWidget->renderer();
svgWidget->resize(render->defaultSize());
}
void SvgWindow::mousePressEvent(QMouseEvent *event)
{
mousePressPos = event->pos();
// 获取水平滑动条和垂直滑动条
scrollBarValueOnMousePress.rx() = horizontalScrollBar()->value();
scrollBarValueOnMousePress.ry() = verticalScrollBar()->value();
event->accept();
}
void SvgWindow::mouseMoveEvent(QMouseEvent *event)
{
horizontalScrollBar()->setValue(scrollBarValueOnMousePress.x() - event->pos().x() + mousePressPos.x());
verticalScrollBar()->setValue(scrollBarValueOnMousePress.y() - event->pos().y() + mousePressPos.y());
horizontalScrollBar()->update();
verticalScrollBar()->update();
event->accept();
}
最后创建一个主窗口界面用于打开SVG图片选项MainWindow
:
#include
#include "svgwindow.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
void createMenu();
private slots:
void slotOpenFile();
private:
SvgWindow *svgWindow;
};
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
this->resize(600, 600);
setWindowTitle(tr("SvgWindow"));
createMenu();
svgWindow = new SvgWindow;
setCentralWidget(svgWindow);
}
MainWindow::~MainWindow()
{
}
void MainWindow::createMenu()
{
QMenu *fileMenu = menuBar()->addMenu(tr("File"));
QAction *openAction = new QAction(tr("open"), this);
connect(openAction, &QAction::triggered, this, &MainWindow::slotOpenFile);
fileMenu->addAction(openAction);
}
void MainWindow::slotOpenFile()
{
QString name = QFileDialog::getOpenFileName(this, "打开", "/", "svg files(*.svg)");
svgWindow->setFile(name);
}
Qt的XML模块支持两种XML解析方法,DOM和SAX。
这里介绍一下DOM的使用方法:
文档对象模型(Document Object Model DOM)能够使程序和脚本动态的存取和更新XML文档的内容、结构和风格。
DOM将XML表示成一颗数,用户通过API可以随意地访问输的任意节点的内容。在Qt中,XML文档自身用QDomDocument
表示。所有的节点都从QDomNode
继承。
SVG是利用XML表示的矢量图形文件,每种图形都用XML标签表示。例如:
<polyline fill="none" stroke="#888888" stroke-width="2" points="100,200,100,100"/>