You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测PDF中用户高亮文本并实现程序化交互?(Python优先)

解决方案

Python 实现方案(优先推荐)

放弃Tkinter,改用PyQt6/PySide6,它们自带的PDF组件原生支持文本选择、高亮,且对键盘热键支持友好。

核心思路

  • 使用 QPdfDocument 加载PDF文件
  • 用 QPdfView 渲染PDF,该组件原生支持鼠标选中文本
  • 通过信号绑定获取选中的文本内容
  • 配置全局热键,触发自定义代码逻辑

示例代码

import sys
from PyQt6.QtWidgets import (QApplication, QMainWindow, QPdfView, QAction)
from PyQt6.QtPdf import QPdfDocument
from PyQt6.QtGui import QKeySequence

class PDFViewer(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("PDF文本选择工具")
        self.resize(800, 600)

        # 初始化PDF组件
        self.pdf_view = QPdfView()
        self.pdf_doc = QPdfDocument()
        self.pdf_view.setDocument(self.pdf_doc)

        # 加载PDF(替换为你的文件路径)
        self.pdf_doc.load("example.pdf")

        # 绑定文本选中信号
        self.pdf_view.selectionChanged.connect(self.on_selection_changed)
        self.selected_text = ""

        # 设置热键:Ctrl+Enter 触发代码运行
        run_action = QAction("运行代码", self)
        run_action.setShortcut(QKeySequence("Ctrl+Return"))
        run_action.triggered.connect(self.run_custom_code)
        self.addAction(run_action)

        self.setCentralWidget(self.pdf_view)

    def on_selection_changed(self):
        # 获取选中的文本
        selection = self.pdf_view.selection()
        self.selected_text = selection.text()
        # 实时显示选中内容长度
        self.statusBar().showMessage(f"选中文本长度: {len(self.selected_text)}")

    def run_custom_code(self):
        if not self.selected_text:
            self.statusBar().showMessage("请先选中文本")
            return
        # 替换为你的自定义代码逻辑
        print("运行代码,输入文本:")
        print(self.selected_text)
        # 示例处理:转大写
        processed = self.selected_text.upper()
        print("处理结果:", processed)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = PDFViewer()
    window.show()
    sys.exit(app.exec())

补充说明

  • 安装依赖:pip install PyQt6
  • 若需自定义选中高亮样式,可通过重写 QPdfView 的绘制事件实现
  • 热键可按需修改,支持组合键、单键等配置

HTML/JavaScript 实现方案

如果对Python GUI不熟悉,用 PDF.js + 轻量Python后端 是更简单的选择,浏览器环境天然支持文本选择和键盘操作。

核心思路

  • 用Mozilla的PDF.js渲染PDF,实现网页端浏览和文本选择
  • 用JavaScript监听文本选中事件,获取选中内容
  • 通过Flask搭建Python后端,用AJAX把选中文本传给后端执行代码
  • 可选:用Electron打包成桌面应用,无需依赖浏览器

示例代码(前端+后端)

前端(index.html)

<!DOCTYPE html>
<html>
<head>
    <title>PDF文本选择工具</title>
    <style>
        #viewerContainer { height: 90vh; width: 100%; }
        .hotkey-hint { position: fixed; bottom: 10px; right: 10px; font-size: 14px; }
    </style>
</head>
<body>
    <div id="viewerContainer"></div>
    <div class="hotkey-hint">热键:Ctrl+Enter 运行代码</div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
    <script>
        // 初始化PDF.js
        const url = 'example.pdf'; // 替换为你的PDF路径
        const pdfjsLib = window['pdfjs-dist/build/pdf'];
        pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.worker.min.js';

        async function renderPDF() {
            const pdf = await pdfjsLib.getDocument(url).promise;
            // 渲染第一页,多页可循环处理
            const page = await pdf.getPage(1);
            const viewport = page.getViewport({ scale: 1.5 });
            const container = document.getElementById('viewerContainer');
            const canvas = document.createElement('canvas');
            const context = canvas.getContext('2d');
            canvas.height = viewport.height;
            canvas.width = viewport.width;
            container.appendChild(canvas);
            await page.render({ canvasContext: context, viewport: viewport }).promise;
        }

        // 获取选中的文本
        function getSelectedText() {
            return window.getSelection().toString().trim();
        }

        // 监听热键
        document.addEventListener('keydown', async (e) => {
            if (e.ctrlKey && e.key === 'Enter') {
                const text = getSelectedText();
                if (!text) {
                    alert('请先选中文本');
                    return;
                }
                // 传给Python后端执行代码
                const response = await fetch('/run-code', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ text: text })
                });
                const result = await response.json();
                console.log('代码运行结果:', result);
                alert('代码运行完成,查看控制台输出');
            }
        });

        renderPDF();
    </script>
</body>
</html>

后端(app.py)

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/run-code', methods=['POST'])
def run_code():
    data = request.get_json()
    selected_text = data.get('text', '')
    
    # 替换为你的自定义代码逻辑
    processed_text = selected_text.lower()
    result = {
        'input': selected_text,
        'output': processed_text,
        'message': '处理完成'
    }
    return jsonify(result)

if __name__ == '__main__':
    app.run(debug=True)

补充说明

  • 运行后端:python app.py,随后在浏览器打开 http://localhost:5000
  • PDF.js支持自定义选中高亮样式,可通过CSS修改文本选中后的外观

内容的提问来源于stack exchange,提问作者cash999

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:43:23