Qt5主窗体构成
QMainWindow是一个为用户提供主窗体程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bar)、多个锚接部件(dock widget)、以及一个中心部件(central widget)。是许多引用程序的基础,如文本编辑器和图片编辑器。
菜单栏
Qt的菜单就是由一系列的QAction对象构成的列表,而菜单栏则是包容菜单的面板,它位于主窗口顶部标题栏的下面,一个主窗口最多只有一个菜单栏。
状态栏
状态栏通常用于显示 GUI程序的状态信息,位于主窗体的最底部,用户可在状态栏上添加、使用Qt窗口部件,一个主窗口最多只有一个状态栏。
工具栏
状态栏是由一系列类似于按钮的动作排列而成的面板,它通常由一些经常使用的动作组成。位于菜单栏的下面一个主窗口可以包含多个工具栏。
锚接部件
锚接部件作为一个容器使用,以包容其它窗口部件来实现某些功能。它位于工具栏内部,可以作为一个窗口自由的浮动在主窗口上面。
中心部件
位于主窗口的中心,锚接部件区的内部。
实例编写
完成一个文本编辑器的实例,针对QMainWindow创建流程和各种功能进行开发。
要完成的功能有:文件的操作功能、标准打印对话框的使用、画图实现图像打印、使用QMatrix实现图像的各种变换功能、最后是排版功能。
新建工程ImageProcessor
,基类选择QMainWindow
。imageprocessor.h
文件用于创建工具栏、各种动作、创建菜单:
#include <QMainWindow>
#include <QMenu>
#include <QToolBar>
#include <QTextCharFormat>
#include <QApplication>
#include <QImage>
#include <QLabel>
#include <QMenuBar>
#include <QDialog>
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QPainter>
// Qt5将打印的这两个类归入到printsupport中,需要在pro文件中写入 QT += printsupport
#include <QPrinter>
#include <QPrintDialog>
#include "showwidget.h"
class ImageProcessor : public QMainWindow
{
Q_OBJECT
public:
ImageProcessor(QWidget *parent = 0);
~ImageProcessor();
void createMenu(); // 创建菜单项
void createAction(); // 创建各种动作
void createToolBars(); // 创建工具栏
void loadFile(QString filename); // 加载文件
void mergeTextFormat(QTextCharFormat);
private:
// 各种菜单栏
QMenu *fileMenu;
QMenu *zoomMenu;
QMenu *rotateMenu;
QMenu *mirrorMenu;
QImage img;
QString fileName;
ShowWidget *showWidget;
// 文件菜单项动作
QAction *openFileAction;
QAction *newFileAction;
QAction *printImgAction;
QAction *printTextAction;
QAction *exitAction;
// 编辑菜单项动作
QAction *copyAction;
QAction *cutAction;
QAction *pasteAction;
QAction *aboutAction;
QAction *zoomInAction;
QAction *zoomOutAction;
// 旋转菜单项动作
QAction *rotate90Action;
QAction *rotate180Action;
QAction *rotate270Action;
// 镜像菜单项动作
QAction *mirrorVerticalAction;
QAction *mirrorHorizontalAction;
QAction *undoAction;
QAction *redoAction;
// 工具栏
QToolBar *fileTool;
QToolBar *zoomTool;
QToolBar *rotateTool;
QToolBar *mirrorTool;
QToolBar *doTool;
private slots:
// 打开窗口函数
void ShowOpenFile();
// 新建窗口函数
void ShowNewFile();
// 打印文本动作
void ShowPrintText();
// 打印图像动作
void ShowPrintImage();
// 图片放大
void ShowZoomIn();
// 图片缩小
void ShowZoomOut();
// 图片旋转
void ShowRotate90();
void ShowRotate180();
void ShowRotate270();
// 图片镜像
void ShowMirrorVertical();
void ShowMirrorHorizontal();
};
imageprocessor.cpp:
#include "imageprocessor.h"
ImageProcessor::ImageProcessor(QWidget *parent)
: QMainWindow(parent)
{
setWindowTitle(tr("MainWindow"));
// 设置showWidget为主窗体的中心部件
showWidget = new ShowWidget(this);
setCentralWidget(showWidget);
createAction();
createMenu();
createToolBars();
if (img.load("image.jpg"))
{
showWidget->imgLabel->setPixmap(QPixmap::fromImage(img.scaled(600, 600)));
}
}
ImageProcessor::~ImageProcessor()
{
}
// 实现各种动作,通过菜单栏和工具栏提现出来
void ImageProcessor::createMenu()
{
// 调用QMainWindow的menuBar()函数即可得到主窗口的菜单指针,
// 在调用菜单条的addMenu()函数,即可完成在菜单中插入一个新菜单
fileMenu = menuBar()->addMenu(tr("file"));
fileMenu->addAction(openFileAction);
fileMenu->addAction(newFileAction);
fileMenu->addAction(printImgAction);
fileMenu->addAction(printTextAction);
// 在各种功能中间加横线分隔
fileMenu->addSeparator();
fileMenu->addAction(exitAction);
zoomMenu = menuBar()->addMenu(tr("zoom"));
zoomMenu->addAction(copyAction);
zoomMenu->addAction(cutAction);
zoomMenu->addAction(pasteAction);
zoomMenu->addAction(aboutAction);
zoomMenu->addSeparator();
zoomMenu->addAction(zoomInAction);
zoomMenu->addAction(zoomOutAction);
rotateMenu = menuBar()->addMenu(tr("rotate"));
rotateMenu->addAction(rotate90Action);
rotateMenu->addAction(rotate180Action);
rotateMenu->addAction(rotate270Action);
mirrorMenu = menuBar()->addMenu(tr("mirror"));
mirrorMenu->addAction(mirrorVerticalAction);
mirrorMenu->addAction(mirrorHorizontalAction );
}
// 各种“动作”的实现
void ImageProcessor::createAction()
{
// 文件操作的实现
openFileAction = new QAction(tr("open"), this);
openFileAction->setShortcut(tr("Ctrl+O")); // 快捷键设置
openFileAction->setStatusTip("Open file"); // 鼠标放上时给出的提示
connect(openFileAction, &QAction::triggered, this, &ImageProcessor::ShowOpenFile);
newFileAction = new QAction(tr("new"), this);
newFileAction->setShortcut(tr("Ctrl+N"));
newFileAction->setStatusTip("New file");
connect(newFileAction, &QAction::triggered, this, &ImageProcessor::ShowNewFile);
exitAction = new QAction(tr("exit"), this);
exitAction->setShortcut(tr("Ctrl+Q"));
exitAction->setStatusTip("Exit");
connect(exitAction, &QAction::triggered, this, &ImageProcessor::close);
copyAction = new QAction(tr("copy"), this);
copyAction->setShortcut(tr("Ctrl+C"));
copyAction->setStatusTip("Copy");
connect(copyAction, &QAction::triggered, showWidget->text, &QTextEdit::copy);
cutAction = new QAction(tr("cut"), this);
cutAction->setShortcut(tr("Ctrl+X"));
cutAction->setStatusTip("Cut");
connect(cutAction, &QAction::triggered, showWidget->text, &QTextEdit::cut);
pasteAction = new QAction(tr("paste"), this);
pasteAction->setShortcut(tr("Ctrl+V"));
pasteAction->setStatusTip("Paste");
connect(pasteAction, &QAction::triggered, showWidget->text, &QTextEdit::paste);
aboutAction = new QAction(tr("about"), this);
connect(aboutAction, &QAction::triggered, this, &QApplication::aboutQt);
printImgAction = new QAction(tr("printImg"), this);
printImgAction->setStatusTip("print image");
connect(printImgAction, &QAction::triggered, this, &ImageProcessor::ShowPrintImage);
printTextAction = new QAction(tr("printText"), this);
printTextAction->setStatusTip("print text");
connect(printTextAction, &QAction::triggered, this, &ImageProcessor::ShowPrintText);
zoomInAction = new QAction(tr("zoomIn"), this);
zoomInAction->setStatusTip("zoom in");
connect(zoomInAction, &QAction::triggered, this, &ImageProcessor::ShowZoomIn);
zoomOutAction = new QAction(tr("zoomOut"), this);
zoomOutAction->setStatusTip("zoom out");
connect(zoomOutAction, &QAction::triggered, this, &ImageProcessor::ShowZoomOut);
rotate90Action = new QAction(tr("rotate90"), this);
rotate90Action->setStatusTip("rotat90");
connect(rotate90Action, &QAction::triggered, this, &ImageProcessor::ShowRotate90);
rotate180Action = new QAction(tr("rotate180"), this);
rotate180Action->setStatusTip("rotat180");
connect(rotate180Action, &QAction::triggered, this, &ImageProcessor::ShowRotate180);
rotate270Action = new QAction(tr("rotate270"), this);
rotate270Action->setStatusTip("rotat270");
connect(rotate270Action, &QAction::triggered, this, &ImageProcessor::ShowRotate270);
mirrorVerticalAction = new QAction(tr("mirrorVertical"), this);
mirrorVerticalAction->setStatusTip("mirrorVertical");
connect(mirrorVerticalAction, &QAction::triggered, this, &ImageProcessor::ShowMirrorVertical);
mirrorHorizontalAction = new QAction(tr("mirrorHorizontal"), this);
mirrorHorizontalAction->setStatusTip("mirrorHorizontal");
connect(mirrorHorizontalAction, &QAction::triggered, this, &ImageProcessor::ShowMirrorHorizontal);
undoAction = new QAction(tr("undo"), this);
undoAction->setStatusTip("undo");
connect(undoAction, &QAction::triggered, showWidget->text, &QTextEdit::undo);
redoAction = new QAction(tr("redo"), this);
redoAction->setStatusTip("redo");
connect(redoAction, &QAction::triggered, showWidget->text, &QTextEdit::redo);
}
// 一个菜单对应一个工具条
void ImageProcessor::createToolBars()
{
// 调用QMainWindow的addToolBar()函数获得窗口的工具条对象
fileTool = addToolBar(tr("File"));
fileTool->addAction(openFileAction);
fileTool->addAction(newFileAction);
fileTool->addAction(printImgAction);
fileTool->addAction(printTextAction);
fileTool->addAction(exitAction);
zoomTool = addToolBar(tr("zoom"));
zoomTool->addAction(copyAction);
zoomTool->addAction(cutAction);
zoomTool->addAction(pasteAction);
zoomTool->addSeparator();
zoomTool->addAction(zoomInAction);
zoomTool->addAction(zoomOutAction);
rotateTool = addToolBar(tr("rotate"));
rotateTool->addAction(rotate90Action);
rotateTool->addAction(rotate180Action);
rotateTool->addAction(rotate270Action);
mirrorTool = addToolBar(tr("mirror"));
mirrorTool->addAction(mirrorVerticalAction);
mirrorTool->addAction(mirrorHorizontalAction);
doTool = addToolBar(tr("do"));
doTool->addAction(undoAction);
doTool->addAction(redoAction);
// 工具条默认是一个可移动的窗口,停靠的区域由QToolBar的allowAreas决定
fileTool->setAllowedAreas(Qt::TopToolBarArea | Qt::LeftToolBarArea);
// 使用setMovable()函数设定可移动性
fileTool->setMovable(false);
}
void ImageProcessor::loadFile(QString filename)
{
// 利用QFile和QTextStream完成读取文件操作
QFile file(filename);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream textStream(&file);
while (!textStream.atEnd())
{
showWidget->text->append(textStream.readLine());
}
}
}
void ImageProcessor::ShowOpenFile()
{
fileName = QFileDialog::getOpenFileName(this);
if (!fileName.isEmpty())
{
if (showWidget->text->document()->isEmpty())
{
loadFile(fileName);
}
else
{
ImageProcessor *newImgProcessor = new ImageProcessor;
newImgProcessor->show();
newImgProcessor->loadFile(fileName);
}
}
}
void ImageProcessor::ShowNewFile()
{
ImageProcessor *newImgProcessor = new ImageProcessor;
newImgProcessor->show();
}
void ImageProcessor::ShowPrintText()
{
// Qt的QPrintDialog提供了标准打印对话框
// 新建一个QPrinter对象
QPrinter printer;
// 新建一个QPrintDialog对象,参数为QPrinter对象
QPrintDialog printDialog(&printer, this);
// 判断用户是否点击了“打印”按钮
if (printDialog.exec())
{
// 获取QTextEdit对象的文档
QTextDocument *doc = showWidget->text->document();
doc->print(&printer);
}
}
void ImageProcessor::ShowPrintImage()
{
QPrinter printer;
QPrintDialog printDialog(&printer, this);
if (printDialog.exec())
{
// 创建一个QPainter对象,指定绘图设备为printer
QPainter painter(&printer);
// 获得QPainter对象的视口矩形区域
QRect rect = painter.viewport();
// 获得图像大小
QSize size = img.size();
// 按照图片的大小重新设置对象矩形区域
size.scale(rect.size(), Qt::KeepAspectRatio);
painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
painter.setWindow(img.rect());
painter.drawImage(0, 0, img);
}
}
void ImageProcessor::ShowZoomIn()
{
if (img.isNull())
return;
// 声明一个Matrix对象
QMatrix matrix;
// 按照两倍的比例对水平和垂直方向进行放大
matrix.scale(2, 2);
// 将当前显示的图形按照该坐标矩阵进行转换
img = img.transformed(matrix);
// 重新设置图形
showWidget->imgLabel->setPixmap(QPixmap::fromImage(img));
}
void ImageProcessor::ShowZoomOut()
{
if (img.isNull())
return;
// 声明一个Matrix对象
QMatrix matrix;
// 按照两倍的比例对水平和垂直方向进行放大
matrix.scale(0.5 , 0.5);
// 将当前显示的图形按照该坐标矩阵进行转换
img = img.transformed(matrix);
// 重新设置图形
showWidget->imgLabel->setPixmap(QPixmap::fromImage(img));
}
void ImageProcessor::ShowRotate90()
{
if (img.isNull())
return;
QMatrix matrix;
matrix.rotate(90);
img = img.transformed(matrix);
showWidget->imgLabel->setPixmap(QPixmap::fromImage(img.scaled(600, 600)));
}
void ImageProcessor::ShowRotate180()
{
if (img.isNull())
return;
QMatrix matrix;
matrix.rotate(180);
img = img.transformed(matrix);
showWidget->imgLabel->setPixmap(QPixmap::fromImage(img.scaled(600, 600)));
}
void ImageProcessor::ShowRotate270()
{
if (img.isNull())
return;
QMatrix matrix;
matrix.rotate(270);
img = img.transformed(matrix);
showWidget->imgLabel->setPixmap(QPixmap::fromImage(img.scaled(600, 600)));
}
void ImageProcessor::ShowMirrorVertical()
{
if (img.isNull())
return;
img.mirrored(false, true);
showWidget->imgLabel->setPixmap(QPixmap::fromImage(img.scaled(600, 600)));
}
void ImageProcessor::ShowMirrorHorizontal()
{
if (img.isNull())
return;
img.mirrored(true, false);
showWidget->imgLabel->setPixmap(QPixmap::fromImage(img.scaled(600, 600)));
}