Qt应用程序主窗口之二:拖放操作与打印文档
一、拖放操作
对于一个实用的应用程序,不仅希望能从文件菜单中打开一个文件,更希望可以通过拖动直接将桌面上的文件拖入程序界面上来打开,就像可以将.pro文件拖入Creator中来打开整个项目一样。Qt中提供了强大的拖放机制,可以在帮助中查看 Drag and Drop 关键字来了解。拖放操作分为拖动(Drag)和放下(Drop)两种操作。 数据拖动时会被存储为 MIME(Multipurpose Internet Mail Extensions) 类型,在 Qt 使用QMimeData类来表示MIME类型的数据,并使用QDrag类来完成数据的转换。而整个拖放操作都是在几个鼠标事件和拖放事件中完成的。
1.1 使用拖放打开文件
下面来看一个很简单的例子,就是将桌面上的txt文本文件拖入程序打开。 新建Qt Gui应用,项目名称改为 myDragDrop 名和基类保持 MainWindow 和 QMainWindow 不变。建立完项目后,往界面上拖入一个Text Edit部件。然后在 mainwindow.h 文件中添加函数声明:
protected:
void dragEnterEvent(QDragEnterEvent *event);
void dropEvent(QDropEvent *event);
然后到 mainwindow. cpp 文件中添加头文件:
#include <QDragEnterEvent>
#include <QUrl>
#include <QFile>
#include <QTextStream>
#include <QMimeData>
然后mainwindow类的构造函数修改位:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setAcceptDrops(true);
}
最后对两个事件处理函数进行定义:
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
if(event->mimeData()->hasUrls())
event->acceptProposedAction();
else
event->ignore();
}
void MainWindow:: dropEvent(QDropEvent *event)
{
const QMimeData *mimeData = event->mimeData(); // 获取MIME数据
if(mimeData->hasUrls()){ // 如果数据中包含URL
QList<QUrl> urlList = mimeData->urls(); // 获取URL列表
// 将其中第一个URL表示为本地文件路径
QString fileName = urlList.at(0).toLocalFile();
if(!fileName.isEmpty()){ // 如果文件路径不为空
QFile file(fileName); // 建立QFile对象并且以只读方式打开该文件
if(!file.open(QIODevice::ReadOnly)) return;
QTextStream in(&file); // 建立文本流对象
ui->textEdit->setText(in.readAll()); // 将文件中所有内容读入编辑器
}
}
}
当鼠标拖拽一个数据进人主窗口时,就会触发dragEvemEvem()事件处理函数, 获取其中的MIME数据,然后査看它是否包含URL路径,因为拖人的文本文件实际上 就是拖人了它的路径,这就是 event→mimeData() →hasUrls()实现的功能。如果有这样的数据就接收它,否则就忽略该事件。QMimeData类中提供了几个函数来方便地处理常见的MIME数据,如下图所示。当松开鼠标左键,将数据放人主窗口时就会触发dropEvent()事件处理函数,这里获取了MIME数据中的URL列表,因为拖入的只 有一个文件,所以获取了列表中的第一个条目,并使用toLocalFile()函数将它转换为本地文件路径。然后使用QFile和QTextStream将文件中的数据读入编辑器中。这时先运行程序,然后从桌面上将一个文本文件拖入程序中。
1.2 自定义拖放操作
书中还有一个在窗口中拖动图片的例子,就是在窗口中有一个图片,可以随意拖动它。这里需要使用到自定义的MIME类型。(项目源码路径:src\05\5-8\imageDrag|Drop)。这里由于篇幅原因,就不再详细说明了。
二、打印文档
Qt中提供了方便的打印文档功能,只需要使用一个QPrinter类和一个打印对话框QPrintDialog类就可以完成文档的打印操作。在这一节将简单介绍一下打印文档、 打印预览和生产PDF文档等操作,也可以在帮助中查看Printing with Qt关键字。
新建Qt Gui应用,项目名称改为myPrint, 类名和基类保持MainWindow和QMainWindow不变。然后在设计模式向界面上拖入一个Text Edit,再到mainwindow. h文件中进行几个槽的声明:
private slots:
void doPrint();
void doPrintPreview();
void printPreview(QPrinter *printer);
void createPdf();
然后到mainwindow. cpp文件中添加头文件:
#include <QPrinter>
#include <QPrintDialog>
#include <QPrintPreviewDialog>
#include <QFileDialog>
#include <QFileInfo>
在构造函数中定义几个动作:
QAction *action_print = new QAction(tr("打印"),this);
QAction *action_printPreview = new QAction(tr("打印预览"),this);
QAction *action_pdf = new QAction(tr("生成pdf"),this);
connect(action_print,SIGNAL(triggered()),this,SLOT(doPrint()));
connect(action_printPreview,SIGNAL(triggered()),this,SLOT(doPrintPreview()));
connect(action_pdf,SIGNAL(triggered()),this,SLOT(createPdf()));
ui->mainToolBar->addAction(action_print);
ui->mainToolBar->addAction(action_printPreview);
ui->mainToolBar->addAction(action_pdf);
然后添加那几个槽的定义:
void MainWindow::doPrint() // 打印
{
QPrinter printer; // 创建打印机对象
QPrintDialog dlg(&printer, this); // 创建打印对话框
// 如果编辑器中有选中区域,则打印选中区域
if (ui->textEdit->textCursor().hasSelection())
dlg.addEnabledOption(QAbstractPrintDialog::PrintSelection);
if (dlg.exec() == QDialog::Accepted) { // 如果在对话框中按下了打印按钮
ui->textEdit->print(&printer); // 则执行打印操作
}
}
这里先建立了QPrinter类对象,它代表了一个打印设备。然后创建了一个打印对话框,如果编辑器中有选中区域则打印该区域,否则打印整个页面。
void MainWindow::doPrintPreview() // 打印预览
{
QPrinter printer;
QPrintPreviewDialog preview(&printer, this); // 创建打印预览对话框
// 当要生成预览页面时,发射paintRequested()信号
connect(&preview, &QPrintPreviewDialog::paintRequested,
this, &MainWindow::printPreview);
preview.exec();
}
void MainWindow::printPreview(QPrinter *printer)
{
ui->textEdit->print(printer);
}
这里主要使用打印预览对话框来进行打印预览,这里要关联它的paimRequestedO信号到我们的槽上,在槽中调用编辑器的打印函数,并以传来的QPrinter类对象指针为参数。
void MainWindow::createPdf() // 生成PDF文件
{
QString fileName = QFileDialog::getSaveFileName(this, tr("导出PDF文件"),
QString(), "*.pdf");
if (!fileName.isEmpty()) {
if (QFileInfo(fileName).suffix().isEmpty())
fileName.append(".pdf"); // 如果文件后缀为空,则默认使用.pdf
QPrinter printer;
printer.setOutputFormat(QPrinter::PdfFormat); // 指定输出格式为pdf
printer.setOutputFileName(fileName);
ui->textEdit->print(&printer);
}
}
在生成PDF文档的槽中,使用文件对话框来获取要保存文件的路径,如果文件名没有指定后缀则为其添加pdf”后缀。然后为QPrinter对象指定输出格式和文件路径,这样就可以将文档打印成PDF格式了。现在运行程序,如果没有安装打印机,那么弹出的打印对话框将无法使用打印操作,打印预览对话框也看不到真实的效果。
Qt应用程序主窗口之二:拖放操作与打印文档的更多相关文章
- Qt中的主窗口之菜单栏
1.Qt中的主窗口 主窗口为建立应用程序用户界面提供了一个框架 Qt开发平台中直接支持主窗口的概念 QMainWindow是Qt中主窗口的基类 QMainWindow继承于QWidget是一种容器类型 ...
- Delphi中,除了应用程序主窗口会显示在任务栏上,其它窗口默认都不会显示在任务栏.
Delphi中,除了应用程序主窗口会显示在任务栏上,其它窗口默认都不会显示在任务栏. Delphi中,除了应用程序主窗口会显示在任务栏上,其它窗口默认都不会显示在任务栏.没有MS开发环境中的ShowI ...
- SpringSecurity权限管理系统实战—二、日志、接口文档等实现
系列目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战 ...
- [Qt Creator 快速入门] 第5章 应用程序主窗口
对于日常见到的应用程序而言,许多都是基于主窗口的,主窗口中包含了菜单栏.工具栏.状态栏和中心区域等.这一章会详细介绍主窗口的每一个部分,还会涉及资源管理.富文本处理.拖放操作和文档打印等相关内容.重点 ...
- PyQt(Python+Qt)学习随笔:Qt Designer中主窗口对象的tabShape属性
tabShape属性用于控制主窗口标签部件(Tab Widget)中的标签的形状,对应类型为QTabWidget.TabShape,有两种取值: 1.QTabWidget.Rounded:对应值为0, ...
- PyQt(Python+Qt)学习随笔:Qt Designer中主窗口对象的toolButtonStyle属性
tooButtonStyle属性保存主窗口工具栏按钮的样式设置,用来表示工具栏按钮的文字和图标怎么显示. 该属性的可设置值类型为枚举类型Qt.ToolButtonStyle,它包含如下值: 该属性的缺 ...
- PyQt(Python+Qt)学习随笔:Qt Designer中主窗口对象的animated属性
animated属性用于设置在操作可浮动部件和工具栏时是否设置动画. 当一个可浮动部件或工具栏被拖到主窗口上时,主窗口将调整其内容,以显示浮动部件或工具栏应该放置的位置.设置此属性后主窗口将使用平滑动 ...
- PyQt(Python+Qt)学习随笔:Qt Designer中主窗口对象dockNestingEnabled属性
dockNestingEnabled 属性是确认主窗口的浮动部件(dock widget)是否允许嵌套的一个属性. 如果此属性为False,则浮动部件停靠区域只能包含一个浮动部件(水平或垂直).如果此 ...
- PyQt(Python+Qt)学习随笔:Qt Designer中主窗口对象documentMode属性
documentMode属性表示当前主窗口是否启用文档模式,如果是则主窗口的选项卡部件会以适合操作文档的模式呈现,这类似于macOS上的文档模式. 设置此属性时,界面上不会呈现选项卡部件框架.此模式当 ...
随机推荐
- 一种小型后台管理系统通用开发框架中的Cache缓存设计
本篇博客记录一下我在实习的公司的后台管理系统开发框架中学习到的一种关于网站的缓存(Cache)的实现方法,我会在弄懂的基础上,将该方法在.net core上进行实现.因为公司开发都是基于.net fr ...
- C# static readonly 修饰符初始化变量
同事问了一个问题,readonly和static啥区别? 我就写了个demo运行了下: /*** * 验证初始化次数:static只初始化一次,无论多少用户访问,在内存中只有一份 * readonly ...
- 华为方舟编译器 下载 和 LiteOS Studio Setup 2019-04-16.exe SDK下载
华为方舟编译器是首个取代Android虚拟机模式的静态编译器,可供开发者在开发环境中一次性将高级语言编译为机器码.此外,方舟编译器未来将支持多语言统一编译,可大幅提高开发效率. 编译器下载 [Ark] ...
- RFID相关知识总结(超高频UHF)
RFID标签分类 1.LF(Low frequency) 低频 频段范围: 125 KHz-135KHz(ISO18000-2) 常见应用:该频段特点是具有良好的物体穿透能力.广泛应用于进出管理.门禁 ...
- PIE SDK 多数据源的复合数据集加载
1. 功能简介 GIS遥感图像数据复合是将多种遥感图像数据融合成一种新的图像数据的技术,是目前遥感应用分析的前沿,PIESDK通过复合数据技术可以将多幅幅影像数据集(多光谱和全色数据)组合成一幅多波段 ...
- Android viewPager+fragment实现滑页效果
先上图,手指在手机向左或者向右滑就可以实现相应的页面切换. 先看activity_main.xml文件,非常简单,主要是三个标题TextView和viewpager <?xml version= ...
- 互联网企业级监控系统 OpenFalcon
Open-Falcon 人性化的互联网企业级监控系统,Open-Falcon 整体可以分为两部分,即绘图组件.告警组件.其中: 安装绘图组件 负责数据的采集.收集.存储.归档.采样.查询.展示(Das ...
- PostgreSQL SQL HINT的使用说明
本文来自:http://www.023dns.com/Database_mssql/5974.html PostgreSQL优化器是基于成本的 (CBO) , (当然, 如果开启了GEQO的话, 在关 ...
- nginx设置开机自启
环境:centos7 nginx1.16.1 方法一:(适用于centos7以上版本) 使用systemctl工具 方法二:(使用多种linux) 使用nginx官方的脚本,设置开机自启
- HDU4747:Mex(线段树区间修改)
传送门 题意: 给出\(n\)个数,然后求\(\sum_{i=1}^n\sum_{j=i}^nmex(i,j)\).\(mex(i,j)\)表示区间\([i,j]\)的\(mex\). 思路: 考虑枚 ...