吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1787|回复: 11
收起左侧

[C&C++ 原创] QT6环境C++实现PDF合并(偷懒版)

[复制链接]
wppele 发表于 2023-11-17 16:11

QT6环境C++实现PDF合并(偷懒版)

市面上PDF合并软件很多,有在线的也有独立的程序。最近学习QTC++,借此机会实现一个简单的PDF合并程序进行练手。之所以说是偷懒版是因为PDF文件处理部分调用了强大的跨平台 PDF 处理工具:cpdf。此为小白练手项目,高手请轻喷哈。{:1_932:}

一、程序界面

程序截图

二、功能介绍

1.添加文件:点击添加文件按钮可进行PDF文件导入,直接将多个PDF文件拖进来也可以。
2.清除按钮:点击清除按钮可删除当前光标选中PDF文件。
3.上移/下移:点击按钮可以调整合并后PDF所在页面。
4.合并:列表内PDF数量大于2则可以进行合并,点击合并按钮选择文件输出路径。

三、目录结构

PDF-merge
—CMakeLists.txt
—HeaderFile
——mainwindow.h
—Source File
——main.cpp
——mainwindow.cpp
—mainWindow.ui
—cpdf.exe

项目源码

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(pdf-merge VERSION 0.1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

set(PROJECT_SOURCES
        main.cpp
        mainwindow.cpp
        mainwindow.h
        mainwindow.ui
)

if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
    qt_add_executable(pdf-merge
        MANUAL_FINALIZATION
        ${PROJECT_SOURCES}
    )
# Define target properties for Android with Qt 6 as:
#    set_property(TARGET pdf-merge APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
#                 ${CMAKE_CURRENT_SOURCE_DIR}/android)
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation
else()
    if(ANDROID)
        add_library(pdf-merge SHARED
            ${PROJECT_SOURCES}
        )
# Define properties for Android with Qt 5 after find_package() calls as:
#    set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")
    else()
        add_executable(pdf-merge
            ${PROJECT_SOURCES}
        )
    endif()
endif()

target_link_libraries(pdf-merge PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
# If you are developing for iOS or macOS you should consider setting an
# explicit, fixed bundle identifier manually though.
if(${QT_VERSION} VERSION_LESS 6.1.0)
  set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.pdf-merge)
endif()
set_target_properties(pdf-merge PROPERTIES
    ${BUNDLE_ID_OPTION}
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

include(GNUInstallDirs)
install(TARGETS pdf-merge
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(pdf-merge)
endif()

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QDragEnterEvent>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    enum movetype{
        movedown,
        moveup
    };
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void utilFileMove(movetype mt,qint8 currentnum);

private slots:    
    void on_merge_btn_clicked();

    void on_fileOpen_btn_clicked();

    void on_clear_btn_clicked();

    void on_up_btn_clicked();

    void on_down_btn_clicked();

private:
    Ui::MainWindow *ui;

protected:
    virtual void dragEnterEvent(QDragEnterEvent* event) override;
    virtual void dropEvent(QDropEvent* event) override;
};
#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "QProcess"
#include "QMessageBox"
#include "QFileDialog"
#include<QMimeData>
#include<QMimeDatabase>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{

    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}
//点击合并按钮进行PDF文件合并
void MainWindow::on_merge_btn_clicked()
{
    QProcess process;
    QStringList arguments;
    //获取listview中pdf路径的数量
    //数量至少两个进行合并操作
    qint8 pdfcount=ui->pdfPathView->count();
    switch (pdfcount) {
    case 0:
        QMessageBox::information(this,"请先添加PDF","请先添加PDF再合并!");
        break;
    case 1:
        QMessageBox::information(this,"PDF数量太少","至少添加两个PDF才能合并!");
        break;
    default:
        QStringList filepaths;
        for(qint8 i=0;i<pdfcount;i++){
            //获取每一个pdf完整路径存入filepaths中
            filepaths.append(ui->pdfPathView->item(i)->text());
        }
        //保存文件的完成路径
        QString savePath = QFileDialog::getSaveFileName(this,"请选择保存路径及名称","","PDF文件(*.pdf)");
        //路径不为空进行合并操作
        if(!savePath.isEmpty()){
            arguments<<filepaths<<"-o"<<savePath;
            QProcess::startDetached("./cpdf.exe",arguments);
            qDebug()<<"合并后文件为"<<savePath;
        }
        break;
    }
}

void MainWindow::on_fileOpen_btn_clicked()
{
    QStringList fileNames={};
    fileNames= QFileDialog::getOpenFileNames(this, QStringLiteral("选择多文件对话框!"), "F:",QStringLiteral("PDF文件(*PDF)"));
    ui->pdfPathView->addItems(fileNames);
}

void MainWindow::on_clear_btn_clicked()
{
    //获取当前选中行
    qint8 currentnum=ui->pdfPathView->currentRow();
    //未选中currentnum值为:-1
    if(currentnum==-1){
        QMessageBox::information(this,"请选择","请选中文件再删除!");
    //有选中行,currentnum值为对应序号
    }else {
        ui->pdfPathView->takeItem(currentnum);
    }
    qDebug()<<currentnum;
}

void MainWindow::on_up_btn_clicked()
{
    movetype mt=moveup;
    qint8 currentnum=ui->pdfPathView->currentRow();
    if(currentnum!=0){
        this->utilFileMove(mt,currentnum);
    }
}

void MainWindow::on_down_btn_clicked()
{
    movetype mt=movedown;
    qint8 currentnum=ui->pdfPathView->currentRow();
    qint8 listcount=ui->pdfPathView->count()-1;
    if(currentnum-listcount!=0){
        this->utilFileMove(mt,currentnum);
    }

}
void MainWindow::utilFileMove(movetype mt,qint8 currentnum){
    //当前信息
    auto *citem = ui->pdfPathView->item(currentnum);
    qDebug()<<currentnum;
        QListWidgetItem *nextitem;
        switch (mt) {
        case movedown:
            nextitem = ui->pdfPathView->item(currentnum+1);
            break;
        case moveup:
            //前一条信息
            nextitem = ui->pdfPathView->item(currentnum-1);
            break;
        default:
            break;
        }
        auto itemtmp= citem->text();
        citem->setText(nextitem->text());
        nextitem->setText(itemtmp);
        //当前选定移到前一个
        ui->pdfPathView->setCurrentItem(nextitem);
}

void MainWindow::dragEnterEvent(QDragEnterEvent* event){
            //允许主窗口接收文件
            event->acceptProposedAction();
}
void MainWindow::dropEvent(QDropEvent* event){
    QMimeDatabase db;
    auto urllist=event->mimeData()->urls();
    for(const QUrl &ur:urllist){
            auto tp=db.mimeTypeForUrl(ur);
            if(tp.name()=="application/pdf"){
            ui->pdfPathView->addItem(ur.toString(QUrl::PreferLocalFile));
            }else{
            QMessageBox::information(this,"文件错误",ur.fileName()+": 非pdf格式文件,已剔除");
            }
            //qDebug()<<tp.name();
    }

}

免费评分

参与人数 5吾爱币 +11 热心值 +3 收起 理由
VLMING + 1 我很赞同!
happyyutong1116 + 1 我很赞同!
Jaxhuang + 1 + 1 学习了
ztt091019 + 1 + 1 用心讨论,共获提升!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

vethenc 发表于 2023-11-17 18:28
感谢分享,学习思路和方法
头像被屏蔽
moruye 发表于 2023-11-17 19:06
lixiong 发表于 2023-12-7 22:14
wopbys 发表于 2024-2-23 13:50
学习下 支持
a525335172 发表于 2024-2-23 16:53
最近也在学qt,学习一下思路
MaGizzZ 发表于 2024-3-10 21:36
来个大佬打包一下,  试试成品,看一下能否展平签名,红章还保留吗
pj52Xiao 发表于 2024-3-14 15:38
请问状态栏如何工作的?
123muxiuyulin 发表于 2024-3-18 09:11
学习了  感谢分享  
头像被屏蔽
time6688 发表于 2024-3-31 12:36
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-11 01:25

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表