制作一个具有我的应用程序透明背景的全屏绘画程序

2024-03-09

我的目标是制作一个小型 PC/Windows 程序,它允许我在屏幕顶部进行绘制,并将结果保存为具有透明背景的 png 格式。像这样的软件Epic Pen https://epic-pen.com/ or gInk https://github.com/geovens/gInk但我的方式。全部使用 Python 3.7 和 PyQt5。

到目前为止,我设法得到了一个功能性的绘图应用程序(基本上遵循本教程 https://www.youtube.com/watch?v=qEgyGyVA1ZQ)因为我同时在学习PyQt。我设法将草稿保存为具有透明背景的 png。我可以使画板全屏且无边框。

现在的问题是,我找不到一种方法使整个背景透明。尽管我找到了使用以下方法使窗口透明且无边框的方法:

Window = Window()
Window.setStyleSheet("background:transparent;")
Window.setAttribute(Qt.WA_TranslucentBackground)
Window.setWindowFlags(Qt.FramelessWindowHint)
Window.show()

它有效......直到我有一个绘图区域。我可以在它上面画画,它会以透明背景保存,但它显示黑色。

所以我正在寻找这个解决方案。即使没有 PyQt,我也不在乎,只要我能让我的程序运行即可。

So here is what I have (I show you windowed with the frame to make it easier to explain): enter image description here

And here is what I want: enter image description here

这是我的代码:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenuBar, QMenu, QAction, QShortcut, QFileDialog
from PyQt5.QtGui import QIcon, QImage, QPainter, QPen
from PyQt5.QtCore import Qt, QPoint


class Window(QMainWindow):
    def __init__(self):
        super().__init__()

        top = 400
        left = 400
        width = 800
        height = 600

        icon = "icons/icon.png"

        self.setWindowTitle("ScreenPen drawing board")
        self.setGeometry(top, left, width, height)
        self.setWindowIcon(QIcon(icon))

# ---------- sets image ----------
        self.image = QImage(self.size(), QImage.Format_RGBA64)
        self.image.fill(Qt.transparent)

# ---------- init drawing state ----------
        self.drawing = False
        self.brushSize = 2
        self.brushColor = Qt.red
        self.lastPoint = QPoint()

# ---------- Define Menus ----------
    # mainmenu
        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu("File")
        toolMenu = mainMenu.addMenu("Tool")
        toolColor = mainMenu.addMenu("Color")
    # smenu save
        saveAction = QAction(QIcon("icons/save.png"), "Save", self)
        saveAction.setShortcut("Ctrl+S")
        fileMenu.addAction(saveAction)
        saveAction.triggered.connect(self.saveFrame)
    # smenu clear frame
        clearFrameAction = QAction(QIcon("icons/clear.png"), "Clear Frame", self)
        clearFrameAction.setShortcut("Ctrl+Del")
        fileMenu.addAction(clearFrameAction)
        clearFrameAction.triggered.connect(self.clearFrame)
    # smenu Tool Pen
        toolPenAction = QAction(QIcon("icons/toolPen.png"), "Pen", self)
        # clearAction.setShortcut("Ctrl+Del")
        toolMenu.addAction(toolPenAction)

# ---------- Catch Mouse Down --------

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.drawing = True
            self.lastPoint = event.pos()

# ---------- Catch Mouse Move --------
    def mouseMoveEvent(self, event):
        if (event.buttons() & Qt.LeftButton) & self.drawing:
            painter = QPainter(self.image)
            painter.setPen(QPen(self.brushColor, self.brushSize, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
            painter.drawLine(self.lastPoint, event.pos())
            self.lastPoint = event.pos()
            self.update()

# ---------- Catch Mouse Up --------
    def mouseReleaseEvent(self, event):
        if event.button == Qt.LeftButton:
            self.drawing = False

# ---------- Paint --------
    def paintEvent(self, event):
        canvasPainter = QPainter(self)
        canvasPainter.drawImage(self.rect(), self.image, self.image.rect())

# ---------- Save Action ----------
    def saveFrame(self):
        filePath,  _ = QFileDialog.getSaveFileName(self, "Save Image", "", "PNG(*.png);;JPEG(*.jpg *.jpeg);; ALL Files(*.*)")
        if filePath == "":
            return
        self.image.save(filePath)

# ---------- Clear Frame Action ----------
    def clearFrame(self):
        self.image.fill(Qt.white)
        self.update()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    Window = Window()
    # Window style
    Window.setStyleSheet("background:transparent;")
    Window.setAttribute(Qt.WA_TranslucentBackground)
    # Window.setWindowFlags(Qt.FramelessWindowHint)
    Window.show()
    app.exec()

实现此目的的一种方法(应该适用于大多数平台)是创建整个桌面的图像,然后将其裁剪到窗口覆盖的区域。这可以在 Qt 中轻松完成,使用QScreen.grabWindow https://doc.qt.io/qt-5/qscreen.html#grabWindow:

def saveFrame(self):
    filePath,  _ = QFileDialog.getSaveFileName(self, "Save Image", "", "PNG(*.png);;JPEG(*.jpg *.jpeg);; ALL Files(*.*)")
    if filePath == "":
        return

    screen = QApplication.desktop().windowHandle().screen()
    wid = QApplication.desktop().winId()
    pixmap = screen.grabWindow(wid, self.x(), self.y(), self.width(), self.height())
    pixmap.save(filePath)

或者可能:

    screen = self.windowHandle().screen()
    pixmap = screen.grabWindow(0, self.x(), self.y(), self.width(), self.height())
    pixmap.save(filePath)

这些都在 Linux 上适用于我,但我还没有在其他平台上测试过它们。如果您还想获取窗框,请使用self.frameGeometry()以获得所需的尺寸。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

制作一个具有我的应用程序透明背景的全屏绘画程序 的相关文章

随机推荐

  • Python类实例变量隔离[重复]

    这个问题在这里已经有答案了 我是一名自学成才的程序员 最近在学习Python 我遇到了一个奇怪的问题 但我想这只是我不了解 python 语法和 或程序流程的结果 我有一堂课叫Test这是文件中的TestClass py class Tes
  • 使用 AngularFire,是否可以创建关系型数据库?或者访问 UniqueID?

    I saw 这个帖子 https www firebase com blog 2013 04 12 denormalizing is normal html在 Firebase 的博客上解释了使用其平台创建关系数据对象的最佳方法 我正在努力
  • Chrome 扩展 - onRequest/sendRequest 与 onMessage/sendMessage [重复]

    这个问题在这里已经有答案了 退房这个示例扩展 http src chromium org viewvc chrome trunk src chrome common extensions docs examples api pageActi
  • 如何完全销毁引导模式窗口?

    我已经利用过模态窗口向导实现大约有 4 5 个步骤 我需要在之后彻底摧毁它最后一步 完成时 和OnCancel 步骤 无需刷新页面 我当然可以隐藏它 但是当我再次打开它时 隐藏模式窗口会恢复所有内容 有人能帮我解决这个问题吗 谢谢 任何提示
  • Tkinter 中的进度条,里面有一个标签

    是否可以改进 Tkinter Python 中的进度条 在中间添加标签 例如 读取文件 我试图找到一个优雅的编码解决方案 但没有真正的结果 from Tkinter import import ttk import tkFileDialog
  • Android 将 JSONArray 读入 JSONArray [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我如何读取包含 json 数组的 json 数组 这是我的 json product name myApp config grade
  • selenium 的 PageFactory 类及其与 FindBy Annotation 一起使用时的工作方式

    我有一个问题 当我使用 FindBy 注释时 Selenium webdriver 的 PageFactory initElements 方法如何工作 我有一段这样的代码 Class PageObject FindBy id usernam
  • 调整 UIAlertView 内 UIPickerView 的大小

    我想放一个UIPickerView in a UIAlertView但我似乎无法正确调整它的大小 这是我得到的 这是我的代码 let alertView UIAlertController title Select item from li
  • Javascript - 异步调用后同步

    我有一个 Javascript 对象 需要 2 次调用外部服务器来构建其内容并执行任何有意义的操作 该对象的构建使得实例化它的实例将自动进行这两个调用 这两个调用共享一个公共回调函数 该函数对返回的数据进行操作 然后调用另一个方法 问题是在
  • Angular Bootstrap 在 Angular 13 项目上给出错误

    我正在尝试安装角度引导程序 https ng bootstrap github io home在我的 Angular 13 项目中 如下所示 ng 添加 ng bootstrap ng bootstrap 但是当我在此语句上按 Y 时 我立
  • 如何在 Ektron 中选择属于某个分类的库项目

    我使用的是 Ektron CMS 版本 8 5 SP2 我有一些分类项目 有些是实际页面 有些是库项目 Word 文件和 PDF 等文档 假设我的分类中有 3 个页面和 2 个库项目 总共 5 个项目 我使用以下代码 ContentMana
  • CakePHP 2.0 $this->表单->input()

    这是我的add tcp 表名称 组 表字段 group id group desc PK group id 这是我的控制器 class GroupsController extends AppController public helper
  • 条形图的峰度、偏度? - Python

    在Python中确定条形图的倾斜 峰度的有效方法是什么 考虑到条形图没有分箱 与直方图不同 这个问题没有多大意义 但我想做的是确定图的高度与距离 而不是频率与箱 的对称性 换句话说 给定沿距离 x 测量的高度 y 值 即 y 6 18 10
  • 为什么 roxygen2 不会自动更新描述文件中的“导入”?

    我正在努力密切关注 hadley sbook http r pkgs had co nz 学习编写 R 包的最佳实践 我很高兴读到这些关于哲学 http r pkgs had co nz intro html本书内容 任何可以自动化的事情都
  • 如何在 ExpressionVisitor 中计算表达式?

    我需要在执行表达式之前使用 ExpressionVisitor 来分析它 根据我的需要 我需要评估除法表达式的正确部分 但我不知道该怎么做 这是我的示例代码 internal class RulesChecker ExpressionVis
  • 将 PostgreSQL text/bytea 列迁移到大对象?

    我有一个表 10k 行 用于存储大值text柱子 当前最大的未压缩大小为 417 MB 烘烤后为 85 MB 此设计的缺陷是无法传输这些值 例如通过 JDBC 使用此列的任何内容都必须将整个内容读入内存 是否有任何工具或快捷方式可用于将此列
  • 聚合查询中的 Mongodb java 展开操作抛出异常

    使用嵌入式 mongo 文档时 我尝试展开数组 但收到类似 org springframework data mapping model MappingInstantiationException Failed to instantiate
  • Qt Widgets 全屏边距

    我想创建一个程序 以全屏方式加载谷歌 所以我使用全屏方式打开了我的qt程序w showFullScreen 它工作得很好 但是当我添加QWebView并将其设置为centralWidget像这样 但是当我运行该程序时 我在窗口的两侧得到了一
  • UIWindow addSubview 上的偏移量

    我有一个基于 UITabBar 的应用程序 运行得很好 在某些情况下 我会显示不同的 UIViewController 现在让我烦恼的是我必须调整测试笔尖的框架 并且only测试笔尖 才能正确显示 否则视图位于状态栏下方 void appl
  • 制作一个具有我的应用程序透明背景的全屏绘画程序

    我的目标是制作一个小型 PC Windows 程序 它允许我在屏幕顶部进行绘制 并将结果保存为具有透明背景的 png 格式 像这样的软件Epic Pen https epic pen com or gInk https github com