吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 27544|回复: 394
收起左侧

[原创工具] 自制上班摸鱼pdf阅读器-更新3.0自动隐藏版本

    [复制链接]
Gitcat 发表于 2025-2-4 10:40
本帖最后由 Gitcat 于 2025-9-11 08:19 编辑

上班的时候,闲来无事,使用python写了一个pdf阅读器,用来摸鱼的,
我们公司电脑装有深信服,上网流量被管控,所以还是决定看一点文学作品来打法点时间,看能不能学到东西

  • 软件截图已上传,
  • 自己工作完成之后,才能摸鱼哦!




1.0版本只能看文字   蓝奏盘: https://wwwp.lanzout.com/ixa512mnnvhe



20250204下午新增:

2.0版本新增图片展示功能:  蓝奏盘:  https://wwwp.lanzout.com/ibbQ42moenij



20250911 新增:

3.0版本: 听同事建议鼠标移开自动隐藏软件,评论区置顶的 是3.0代码 与 环境依赖  蓝奏盘:  https://wwwp.lanzout.com/izdfE35whg4d[/backcolor]





[Python] 纯文本查看 复制代码
import tkinter as tk
from tkinter import scrolledtext, messagebox, filedialog, simpledialog
import PyPDF2
import threading

class PDFViewerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Viewer")
        self.password = "8"  # 硬编码密码
        self.mouse_position = (0, 0)  # 初始化鼠标位置

        # 创建密码输入对话框
        self.password_dialog = simpledialog.askstring("Password", "Enter password:", show="*")
        if self.password_dialog != self.password:
            messagebox.showerror("Error", "Incorrect password!")
            self.root.destroy()
            return

        # 创建按钮
        self.open_button = tk.Button(root, text="Choose a PDF file", command=self.choose_pdf)
        self.open_button.pack(pady=10)

        # 创建滚动文本框
        self.text_area = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=50, height=15)
        self.text_area.pack(padx=10, pady=10)

        # 创建进度标签
        self.progress_label = tk.Label(root, text="")
        self.progress_label.pack(pady=5)

        # 创建鼠标位置标签
        #self.mouse_label = tk.Label(root, text=f"Mouse Position: ({self.mouse_position[0]}, {self.mouse_position[1]})")
        #self.mouse_label.pack(pady=5)

        # 创建遮罩层
        self.mask = tk.Frame(root, bg="white")#white
        self.mask.place(relwidth=0, relheight=0)  # 初始位置不覆盖任何区域
        self.mask.place_forget()  # 初始隐藏遮罩层

        # 绑定鼠标移动事件
        self.root.bind("<Motion>", self.update_mouse_position)
        self.root.bind("<Leave>", self.show_mask)  # 鼠标离开窗口时显示遮罩
        self.root.bind("<Enter>", self.hide_mask)   # 鼠标进入窗口时隐藏遮罩

    def choose_pdf(self):
        file_path = filedialog.askopenfilename(
            filetypes=[("PDF files", "*.pdf")],  # 只允许选择PDF文件
            title="Choose a PDF file"
        )
        if file_path:  # 如果用户选择了文件
            self.load_pdf_in_thread(file_path)

    def load_pdf_in_thread(self, pdf_path):
        # 启动新线程加载PDF文件
        threading.Thread(target=self.open_pdf, args=(pdf_path,), daemon=True).start()
        self.progress_label.config(text="Loading PDF...")

    def open_pdf(self, pdf_path):
        try:
            with open(pdf_path, 'rb') as file:
                reader = PyPDF2.PdfReader(file)
                num_pages = len(reader.pages)

                self.text_area.delete('1.0', tk.END)  # 清除之前的内容

                for page_num in range(num_pages):
                    page = reader.pages[page_num]
                    text = page.extract_text()
                    self.text_area.insert(tk.END, text)
                    self.text_area.insert(tk.END, '\n' + '='*40 + '\n')  # 页面之间的分隔符

                    # 使用after方法从线程更新GUI
                    self.root.after(0, self.update_progress_label, f"Page {page_num + 1}/{num_pages} loaded")

            self.root.after(0, self.progress_label.config, {'text': ""})

        except Exception as e:
            self.root.after(0, lambda: messagebox.showerror("Error", str(e)))
            self.root.after(0, self.progress_label.config, {'text': ""})

    def update_progress_label(self, text):
        self.progress_label.config(text=text)

    def update_mouse_position(self, event):
        self.mouse_position = (event.x, event.y)
        #self.mouse_label.config(text=f"Mouse Position: ({self.mouse_position[0]}, {self.mouse_position[1]})")

        # 更新遮罩层位置和大小
        if self.mask.winfo_ismapped():  # 如果遮罩层可见
            self.mask.place(relx=0, rely=0, relwidth=1, relheight=1)  # 根据PDF预览区域调整遮罩层

    def show_mask(self, event):
        self.mask.place(relx=0, rely=0, relwidth=1, relheight=1)  # 覆盖PDF预览区域

    def hide_mask(self, event):
        self.mask.place_forget()  #


if __name__ == "__main__":
    root = tk.Tk()
    app = PDFViewerApp(root)
    root.mainloop()

新增提示

新增提示

新增隐藏按钮

新增隐藏按钮

正常摸鱼的画面

正常摸鱼的画面

鼠标离开软件,自动遮罩挡住内容

鼠标离开软件,自动遮罩挡住内容

软件启动,输入设定的密码

软件启动,输入设定的密码

免费评分

参与人数 110吾爱币 +98 热心值 +95 收起 理由
muzhe + 1 我很赞同!
strugglepan + 1 + 1 用心讨论,共获提升!
snake820217 + 1 + 1 我很赞同!
zxsz010 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
sorfy + 1 + 1 我很赞同!
chakins + 1 + 1 谢谢@Thanks!
papapo + 1 + 1 热心回复!
英文咯 + 1 + 1 用心讨论,共获提升!
bui666666 + 1 我很赞同!
chenshixianshen + 1 谢谢@Thanks!
gaoshuhao + 1 + 1 谢谢@Thanks!
shenguan7 + 1 + 1 我很赞同!
RadianceFang + 1 热心回复!
lightupdown + 1 热心回复!
xinmi18 + 1 请问,改视图或密码,具体怎么操作??
ijie + 1 + 1 我很赞同!
zh2009 + 1 + 1 我很赞同!
tvrcfdfe + 1 + 1 我很赞同!
haoyangge + 1 + 1 谢谢@Thanks!
Zhaofeiyan + 1 用心讨论,共获提升!
xiaomr1990 + 1 + 1 谢谢@Thanks!
wjt1 + 1 + 1 我很赞同!
JH1CR7 + 1 我很赞同!
xn2113 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
fuming2023 + 1 + 1 我很赞同!
klmytwb + 1 + 1 谢谢@Thanks!
wuqing89403 + 1 + 1 谢谢@Thanks!
liaocwvae + 1 + 1 我很赞同!
MrWiFi + 1 + 1 我很赞同!
xljh888 + 1 + 1 谢谢@Thanks!
fzo + 1 + 1 谢谢@Thanks!
huangyongwen + 1 我很赞同!
ccgao + 1 + 1 谢谢@Thanks!
qingne0130 + 1 + 1 我很赞同!
xiaotao921 + 1 + 1 谢谢@Thanks!
hus + 1 谢谢@Thanks!
sakura0 + 1 热心回复!
xuq1981 + 1 + 1 谢谢@Thanks!
wanfen11 + 1 我很赞同!
kkiitt + 1 + 1 谢谢@Thanks!
debugok + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
viconly + 1 + 1 我很赞同!
Tusimple + 1 + 1 热心回复!
sjb5201314 + 1 + 1 谢谢@Thanks!
0328 + 1 + 1 用心讨论,共获提升!
Xpt978 + 1 谢谢@Thanks!
cxb2468 + 1 我很赞同!
aisheying1212 + 1 我很赞同!
dzc999 + 1 + 1 谢谢@Thanks!
ag129 + 1 + 1 谢谢@Thanks!
YYL7535 + 1 谢谢@Thanks!
sbsnqq123 + 1 + 1 我很赞同!
yiwenji + 1 我很赞同!
yx69 + 1 + 1 我很赞同!
Briller + 1 + 1 我很赞同!
kobeLau + 1 + 1 谢谢@Thanks!
miyatotora + 1 + 1 谢谢@Thanks!
Tiniaual + 1 + 1 谢谢@Thanks!
zhangwei6929 + 1 + 1 谢谢@Thanks!
grrr_zhao + 1 + 1 谢谢@Thanks!
dkyueya + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
zj_tj + 1 + 1 热心回复!
shouwanglove + 1 谢谢@Thanks!
Zsh251618 + 1 谢谢@Thanks!
yxpp + 1 谢谢@Thanks!
y107620560 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
zhiyuckt + 1 热心回复!
Blueyes + 1 + 1 谢谢@Thanks!
JimOvO + 1 热心回复!
ssq + 1 + 1 谢谢@Thanks!
主骑士 + 1 + 1 谢谢@Thanks!
aminqiu1015 + 1 + 1 谢谢@Thanks!
mufeng9527 + 1 + 1 热心回复!
sqln0324 + 1 + 1 这个可以有
lj113590797 + 1 + 1 谢谢@Thanks!
cyc1307 + 1 + 1 我很赞同!
misaki520 + 1 + 1 已经处理,感谢您对吾爱破解论坛的支持!
Lingjohnny + 1 我很赞同!
card628 + 1 热心回复!
zhulingfenga + 1 + 1 我很赞同!
classSTU00 + 1 我很赞同!
gbm15651075073 + 1 热心回复!
xiiye + 1 我很赞同!
Peanutegg + 1 + 1 谢谢@Thanks!
pdcba + 1 + 1 谢谢@Thanks!
wang82530 + 1 + 1 鼓励转贴优秀软件安全工具和文档!
高高的洁白的花 + 1 + 1 我很赞同!
hyeiz + 1 + 1 谢谢@Thanks!
风之暇想 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
wanfon + 1 + 1 热心回复!
yhy123456 + 1 + 1 我很赞同!
aaddmmiinn + 1 我很赞同!
chuiyuanwo + 1 + 1 用心讨论,共获提升!
huawuya + 1 + 1 谢谢@Thanks!
liwei69288 + 1 + 1 我很赞同!
woyaodl + 1 + 1 我很赞同!
meet52 + 1 + 1 我很赞同!
Camus2021 + 1 + 1 谢谢@Thanks!
Diamondzl + 1 + 1 谢谢@Thanks!
zhhmok + 1 我很赞同!

查看全部评分

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

 楼主| Gitcat 发表于 2025-2-4 14:29
本帖最后由 Gitcat 于 2025-2-4 14:36 编辑

2.0版本接入:  pdf內图片展示功能

===========================

原来的代码使用PyPDF2库,但PyPDF2的extract_text方法只能提取文本,无法处理图片,所以引入了 PyMuPDF(即fitz)库,可以同时处理图片与文字

===========================

蓝奏云: https://wwwp.lanzout.com/ibbQ42moenij

ps:  就引了两个包,怎么打包后体积直接干到30M?

==============================

改启动密码: self.password = "8"  # 硬编码密码
改视图大小: self.text_area = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=50, height=15)

==============================

依赖安装指令:  pip install PyMuPDF Pillow

==============================


[Python] 纯文本查看 复制代码
import tkinter as tk
from tkinter import scrolledtext, messagebox, filedialog, simpledialog
import threading
import fitz
from PIL import Image, ImageTk
import io

class PDFViewerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Viewer")
        self.password = "8"  # 硬编码密码
        self.mouse_position = (0, 0)
        self.image_references = []  # 保存图片引用防止被回收

        # 密码验证
        self.password_dialog = simpledialog.askstring("Password", "Enter password:", show="*")
        if self.password_dialog != self.password:
            messagebox.showerror("Error", "Incorrect password!")
            self.root.destroy()
            return

        # 界面组件
        self.open_button = tk.Button(root, text="Choose a PDF file", command=self.choose_pdf)
        self.open_button.pack(pady=10)

        self.text_area = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=50, height=15)
        self.text_area.pack(padx=10, pady=10)

        self.progress_label = tk.Label(root, text="")
        self.progress_label.pack(pady=5)

        # 遮罩层
        self.mask = tk.Frame(root, bg="white")
        self.mask.place(relwidth=0, relheight=0)
        self.mask.place_forget()

        # 事件绑定
        self.root.bind("<Motion>", self.update_mouse_position)
        self.root.bind("<Leave>", self.show_mask)
        self.root.bind("<Enter>", self.hide_mask)

    def choose_pdf(self):
        file_path = filedialog.askopenfilename(
            filetypes=[("PDF files", "*.pdf")],
            title="Choose a PDF file"
        )
        if file_path:
            self.load_pdf_in_thread(file_path)

    def load_pdf_in_thread(self, pdf_path):
        threading.Thread(target=self.open_pdf, args=(pdf_path,), daemon=True).start()
        self.progress_label.config(text="Loading PDF...")

    def open_pdf(self, pdf_path):
        try:
            doc = fitz.open(pdf_path)
            num_pages = len(doc)
            
            # 清空之前的内容和图片引用
            self.root.after(0, self.clear_content)
            
            for page_num in range(num_pages):
                page = doc.load_page(page_num)
                text = page.get_text()
                images = self.extract_images_from_page(doc, page)
                
                # 将当前页内容添加到GUI
                self.root.after(0, self.insert_page_content, text, images)
                self.root.after(0, self.update_progress_label, f"Page {page_num+1}/{num_pages} loaded")
            
            self.root.after(0, self.progress_label.config, {'text': ""})
            doc.close()
        except Exception as e:
            self.root.after(0, lambda: messagebox.showerror("Error", str(e)))
            self.root.after(0, self.progress_label.config, {'text': ""})

    def extract_images_from_page(self, doc, page):
        images = []
        image_list = page.get_images(full=True)
        for img in image_list:
            xref = img[0]
            base_image = doc.extract_image(xref)
            image_data = base_image["image"]
            
            # 转换图像尺寸
            pil_image = Image.open(io.BytesIO(image_data))
            pil_image.thumbnail((400, 400))  # 调整图片尺寸
            tk_image = ImageTk.PhotoImage(pil_image)
            images.append(tk_image)
        return images

    def clear_content(self):
        self.text_area.delete('1.0', tk.END)
        self.image_references.clear()

    def insert_page_content(self, text, images):
        self.text_area.insert(tk.END, text + "\n")
        for img in images:
            self.image_references.append(img)  # 保持引用
            self.text_area.image_create(tk.END, image=img)
            self.text_area.insert(tk.END, "\n")
        self.text_area.insert(tk.END, "\n" + "="*60 + "\n\n")
        self.text_area.see(tk.END)  # 滚动到最新内容

    def update_progress_label(self, text):
        self.progress_label.config(text=text)

    def update_mouse_position(self, event):
        self.mouse_position = (event.x, event.y)
        if self.mask.winfo_ismapped():
            self.mask.place(relx=0, rely=0, relwidth=1, relheight=1)

    def show_mask(self, event):
        self.mask.place(relx=0, rely=0, relwidth=1, relheight=1)

    def hide_mask(self, event):
        self.mask.place_forget()

if __name__ == "__main__":
    root = tk.Tk()
    app = PDFViewerApp(root)
    root.mainloop()


引入图片展示功能.png
 楼主| Gitcat 发表于 2025-9-11 08:17
[Python] 纯文本查看 复制代码
import tkinter as tk
from tkinter import scrolledtext, messagebox, filedialog, simpledialog
import PyPDF2
import threading
from pynput import keyboard as pynput_keyboard


class PDFViewerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("PDF Reader")
        self.password = "8"  # 硬编码密码

        # 密码验证
        password_input = simpledialog.askstring("密码检测", "输入密码:", show="*")
        if password_input != self.password:
            messagebox.showerror("错误", "密码错误!")
            self.root.destroy()
            return

        # &#128073; 密码正确后,弹出使用提示
        messagebox.showinfo(
            "使用提示",
            "请先调整窗口大小和位置,\n"
            "打开PDF文档后,再点击[hide]按钮。\n"
            "后续可使用 F8 快捷键呼出窗口。"
        )

        # 窗口初始大小
        self.root.geometry("350x400")

        # 是否启用自动隐藏
        self.hide_window_var = tk.BooleanVar(value=False)
        self.hide_checkbox = tk.Checkbutton(
            root,
            text="hide",
            variable=self.hide_window_var,
            command=self.on_hide_checkbox_change  # 可扩展
        )
        self.hide_checkbox.pack(pady=5)

        # 打开PDF按钮
        self.open_button = tk.Button(root, text="选择pdf文件", command=self.choose_pdf)
        self.open_button.pack(pady=10)

        # 滚动文本框
        self.text_area = scrolledtext.ScrolledText(root, wrap=tk.WORD, width=60, height=15)
        self.text_area.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)

        # 进度标签
        self.progress_label = tk.Label(root, text="")
        self.progress_label.pack(pady=5)

        # 绑定鼠标离开事件:仅当勾选“隐藏”时自动隐藏
        self.root.bind("<Leave>", self.on_leave_window)

        # 启动周期性检查(可用于未来扩展,如监听状态)
        self.root.after(100, self.periodic_check)

        # 启动全局快捷键监听
        self.start_keyboard_listener()

    def start_keyboard_listener(self):
        """启动 F8 全局快捷键监听"""
        def on_press(key):
            if key == pynput_keyboard.Key.f8:
                self.root.after(0, self.toggle_window)  # 安全调用主线程

        listener = pynput_keyboard.Listener(on_press=on_press)
        listener.start()
        self.listener = listener  # 保持引用

    def on_leave_window(self, event):
        """鼠标离开窗口时,延迟检查是否需隐藏"""
        if self.hide_window_var.get():
            self.root.after(10, self.check_mouse_after_delay)

    def check_mouse_after_delay(self):
        """延迟后检查鼠标是否在窗口外"""
        try:
            x, y = self.root.winfo_rootx(), self.root.winfo_rooty()
            w, h = self.root.winfo_width(), self.root.winfo_height()
            mouse_x, mouse_y = self.root.winfo_pointerx(), self.root.winfo_pointery()

            if not (x <= mouse_x <= x + w and y <= mouse_y <= y + h):
                self.hide_window()
        except Exception:
            pass

    def toggle_window(self):
        """切换窗口显隐"""
        try:
            if self.root.state() == 'withdrawn':
                self.show_window()
            else:
                self.hide_window()
        except Exception:
            pass

    def show_window(self):
        """显示窗口并置顶"""
        self.root.deiconify()
        self.root.focus_force()
        self.root.lift()
        self.root.attributes('-topmost', True)
        self.root.after(100, lambda: self.root.attributes('-topmost', False))

    def hide_window(self):
        """隐藏窗口"""
        if self.root.state() != 'withdrawn':
            self.root.withdraw()

    def choose_pdf(self):
        """选择并加载PDF"""
        file_path = filedialog.askopenfilename(
            filetypes=[("PDF files", "*.pdf")],
            title="选择PDF文件"
        )
        if file_path:
            self.load_pdf_in_thread(file_path)

    def load_pdf_in_thread(self, pdf_path):
        """异步加载PDF"""
        threading.Thread(target=self.open_pdf, args=(pdf_path,), daemon=True).start()
        self.progress_label.config(text="正在加载PDF...")

    def open_pdf(self, pdf_path):
        """读取PDF内容"""
        try:
            with open(pdf_path, 'rb') as file:
                reader = PyPDF2.PdfReader(file)
                num_pages = len(reader.pages)
                self.text_area.delete('1.0', tk.END)

                for page_num in range(num_pages):
                    page = reader.pages[page_num]
                    text = page.extract_text()
                    self.text_area.insert(tk.END, text)
                    self.text_area.insert(tk.END, '\n' + '=' * 40 + '\n')
                    self.root.after(0, self.update_progress_label, f"第 {page_num + 1}/{num_pages} 页")

            self.root.after(0, self.progress_label.config, {'text': ""})
        except Exception as e:
            self.root.after(0, lambda: messagebox.showerror("错误", f"加载失败:{str(e)}"))
            self.root.after(0, self.progress_label.config, {'text': ""})

    def update_progress_label(self, text):
        self.progress_label.config(text=text)

    def on_hide_checkbox_change(self):
        """隐藏选项变化时的回调(预留扩展)"""
        pass

    def periodic_check(self):
        """周期性任务(可扩展)"""
        self.root.after(100, self.periodic_check)


if __name__ == "__main__":
    root = tk.Tk()
    app = PDFViewerApp(root)
    root.mainloop()
myconan 发表于 2025-2-4 11:17
我公司办公场所都安装了监控摄像头,发现摸鱼罚款1000元并警告一次,三次警告直接卷铺盖走人

点评

这么专业的反摸鱼?  发表于 2025-2-4 20:14

免费评分

参与人数 1吾爱币 +1 收起 理由
Jianguan12345 + 1 这个也太狠了

查看全部评分

wbjjfans 发表于 2025-2-4 11:48
首先感谢分享这个小工具,提点意见:
1、pdf图片不能显示出来,全显示的文字。
2、pdf文档显示窗口太小,四周空边太多,如果能扩大显示窗口就更好了。
XMAD 发表于 2025-2-4 10:44
感谢分享。
lmyx2008 发表于 2025-2-4 10:50
用python写程序,棒
ccxk 发表于 2025-2-4 11:00
摸鱼必备,能实现鼠标移开范围后,整个窗口隐藏吗
easylan 发表于 2025-2-4 11:12
呵呵~有点意思
qqpoly 发表于 2025-2-4 11:20
ccxk 发表于 2025-2-4 11:00
摸鱼必备,能实现鼠标移开范围后,整个窗口隐藏吗

那得先想想,想唤出界面时怎么操作啊
guohuanxian 发表于 2025-2-4 11:23
上班可以无忧无虑的摸鱼了
kangta520 发表于 2025-2-4 11:25
能查看图片内容就好了
Kizzrzz 发表于 2025-2-4 11:32
谢谢楼主的分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2026-7-20 07:51

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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