qt编程技巧(3)

MainWindow的中央窗口部件可以为:
一个标准的Qt窗口部件;
一个自定义的窗口部件;
一个带布局管理器的普通QWidget;
一个切分窗口(QSplitter);
一个多文档工作空间(QMdiArea)。

读写平台无关的二进制文件
bool writeFile(QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
{
QMessageBox::warning(this, tr(“”), tr(“Can not write file %1:\n%2”)
.arg(file.fileName()).arg(file.errorString()));
return false;
}
QDataStream out(&file);
out.setVersion(QDataStream::Qt_4_6);
out << quint32(0X11223344);
QApplication::setOverrideCursor(Qt::WaitCursor);
out << quint8(x) << qint32(y) << QString(str);
out << …

QApplication::restoreOverrideCursor();
return true;
}
bool readFile(QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly))
{
QMessageBox::warning(this, tr(“”), tr(“Can not read file %1:\n%2”)
.arg(file.fileName()).arg(file.errorString()));
return false;
}
QDataStream in(&file);
in.setVersion(QDataStream::Qt_4_6);

quint32 magic;
in >> magic;
if (magic != 0x11223344)
{
QMessageBox::warning(this, tr(“”), tr(“The file is not a xxx file.”));
return false;
}
QApplication::setOverrideCursor(Qt::WaitCursor);
quint8 x;
qint32 y;
QString str;
while (!in.end())
{
in >> x >> y >> str;
in >> …

}
QApplication::restoreOverrideCursor();
return true;
}
创建一个自定义窗口部件的过程:
选择一个合适的窗口部件;
对它子类化;
实现虚函数,改变它的行为。

构建一个可以集成到Qt设计师中的窗口部件
// iconeditor.h
#ifndef ICONEDITOR_H
#define ICONEDITOR_H

#include
#include
#include

class IconEditor : public QWidget
{
Q_OBJECT // 必须
//设计师的属性编辑器显示这些自定义属性
Q_PROPERTY(QImage iconImage READ iconImage WRITE setIconImage)
Q_PROPERTY(int zoomFactor READ zoomFactor WRITE setZoomFactor)

public:
IconEditor(QWidget *parent = 0);
void setIconImage(const QImage &image);
QImage iconImage() const { return image; }
void setZoomFactor(int zoom);
int zoomFactor() const { return zoom; }
QSize sizeHint() const; // 窗口的理性尺寸

protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event); // 必须

private:
QImage image;
int zoom;
};

#endif

IconEditor::IconEditor(QWidget *parent)
: QWidget(parent)
{
setAttribute(Qt::WA_StaticContents);
// 告诉布局管理器,理想尺寸是它的最小尺寸,不能对它缩小!
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
zoom = 8; // 一个像素将显示成一个8x8的正方形
image = QImage(16, 16, QImage::Format_ARGB32); // 16x16像素的图片
image.fill(qRgba(0, 0, 0, 0)); // 黑色,完全透明
}
void IconEditor::sizeHint() const
{
QSize size = zoom * image.size();
if (zoom >=3)
size += QSize(1, 1);
return size;
}
void IconEditor::setIconImage(const QImage &img)
{
if (img != image)
{
image = img.convertToFormat(QImage::Format_ARGB32);
update(); // 重绘窗口
updateGeometry(); // 告诉布局管理器,理想尺寸已经发生改变,布局需要调整
}
}
自动调用的情况:
窗口第一次显示;
大小改变;
被遮挡,然后再次显示。

主动调用的情况:
update();
repaint(); // 不常用
void IconEditor::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setPen(palette().forground().color()); // 调色板
painter.drawLine(…);
}
void IconEditor::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
setImagePixel(event->pos(), true);

}
else if (event->button() == Qt::LeftButton)
{
setImagePixel(event->pos(), false);

}
}
窗口属性Qt::WA_StaticContents
当重新改变窗口部件的大小时,窗口部件的内容并没有发生改变,
而且内容仍旧保留从窗口左上角开始的特性。这样就可以避免重绘
已经显示的区域。

在设计师中集成自定义窗口部件的2种方法
提升法:拖动一个自定义窗口的父窗口对象,右键->提示为…
插件法:创建一个插件库

当应用程序的最后一个窗口关闭时,程序退出
在main中使用下面语句:
QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) );

键盘:
Qt::Key_Plus: 对数字小键盘起作用,对于大键盘,要同时按下Shift
Qt::Key_Enter: 对数字小键盘起作用

当定义一个函数时,如果不没有用到其中的参数p,但又不想在编译时,产生警告:
在函数的开头,使用宏
Q_UNUSED(p);
在QGraphicsItem的paint函数中,如果不希望线的宽度缩放,则
painter->setPen(color); //不指定pen的宽度 ,或者指定为0