zoukankan      html  css  js  c++  java
  • 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类型。(项目源码路径:src55-8imageDrag|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格式了。现在运行程序,如果没有安装打印机,那么弹出的打印对话框将无法使用打印操作,打印预览对话框也看不到真实的效果。


  • 相关阅读:
    nginx 、tomcat 配置表单附件大小限制
    清理redis服务器数据
    tomcat 8.5.55 webapps 无法部署应用目录 org.apache.catalina.startup.HostConfig.deployDirectory
    redis + tomcat8.5 session共享
    linux tar 打包
    mysql ORDER BY RAND() 语句优化
    解决Linux下程序端口占用问题
    javamail邮件发送开发中SharedByteArrayInputStream类找不到的错误(java.lang.NoClassDefFoundError: com/sun/mail/util/SharedByteArrayInputStream)
    ansible判定文件或者文件夹是否存在
    ansible应用
  • 原文地址:https://www.cnblogs.com/linuxAndMcu/p/10133924.html
Copyright © 2011-2022 走看看