当前位置:首页 > 编程笔记 > 正文
已解决

PyQt6实战开发之旅-代码均可运行

来自网友在路上 11328132提问 提问时间:2023-11-26 20:31:58阅读次数: 132

最佳答案 问答题库1328位专家为你答疑解惑


在这里插入图片描述

学习感悟

由于官方文档是英文的,所以学习起来不是很直观。
网上的中文教程也都有点偏重就轻,去从头学习细枝末节不是很必要。假如每个控件组件讲十分钟,几百个控件可想而知。
最关键的是有python基础,能理解类与继承,函数调用这些东西。所有教程都过分强调信号与槽这个东西,很大可能他面向的学习对象是零基础的学生,但是你有基础的话一看就明白了,无非就是某些事件发出个信号然后调用函数的过程。
所以我的学习方法就是弄清楚,PyQt6中有哪些模块,每个模块中有哪些组件,每个组件是什么功能,体现在软件上是什么样,有一个直观的认识之后。
就怼着一个目标开始我们的编程。开始设计一款自己的软件,怼着那些厉害的软件模仿功能,我这里就直接模仿者vscode来做了,过程中整理记录好笔记,等软件做出来,自己肯定收获不小。
不然你从头到尾看完教程,才开始实战,这个时候前面学的又忘光了,很消耗人的。
所以说不要一开始就在认知不清楚的时候盲目看教程,很可能看个标签,按钮什么的各种都敲一敲。其实每个细节你都不用太细究,你只需要有个清晰的整体认知,需要使用的时候直接搜索查询拿来使用就好了。

简介

PyQt6组成模块及功能

QtCore
QtGui
QtWidgets
QtDBus
QtNetwork
QtHelp
QtXml
QtSvg
QtSql
QtTest
  • QtCore:这个模块提供了一些基本的功能,如时间处理、文件和目录处理、数据类型、流、属性系统、元对象系统等。
  • QtGui:这个模块是PyQt6中的图形用户界面(GUI)工具集,它提供了一些窗口系统、事件处理、2D图形和基本的图像类等功能。
  • QtWidgets:这个模块是建立在QtGui之上的一套新的控件,它提供了一套丰富的控件集合,例如按钮、文本框、列表框、复选框等。
  • QtDBus:这个模块实现了DBus的底层访问,使得应用程序可以通过DBus进行通信。
  • QtNetwork:这个模块提供了实现网络编程的类和方法,如网络请求和响应、SSL安全连接等。
  • QtHelp:这个模块用于创建帮助文件,支持多种格式,如HTML、XML等。
  • QtXml:这个模块实现了解析和生成XML文档的功能。
  • QtSvg:这个模块提供了将SVG文件转换为QPainter绘图的命令。
  • QtSql:这个模块实现了SQL数据库的访问功能,可以执行SQL语句以及获取查询结果。
  • QtTest:这个模块包含了一些测试工具,用于单元测试和集成测试。

模块所处位置

from PyQt6.QtWidgets import QApplication, QMainWindow, QMenu
from PyQt6.QtGui import QAction,QIcon

版本信息

# QT_VERSION_STR 可以显示 Qt 的版本信息,PYQT_VERSION_STR 可以显示 PyQt 的版本信息
from PyQt6.QtCore import QT_VERSION_STR
from PyQt6.QtCore import PYQT_VERSION_STRprint(QT_VERSION_STR)
print(PYQT_VERSION_STR)

程序实战

第一个程序

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel
from PyQt6.QtGui import QIcondef main():app = QApplication(sys.argv)window = QMainWindow()window.setGeometry(100, 100, 300, 200) window.setWindowTitle("派森斗罗")window.setWindowIcon(QIcon('logo.png'))QLabel("Hello, World!", window)window.show()sys.exit(app.exec())if __name__ == "__main__":main()

居中显示窗口

  • self.frameGeometry() 返回一个 QRect 对象,该对象表示小组件相对于其父级的几何图形,包括任何窗口框架。
  • QGuiApplication.primaryScreen().availableGeometry().center() 返回一个 QPoint 对象,该对象表示主屏幕的可用几何图形的中心点。
  • 此线移动矩形 ( qr ) 的左上角,使其中心位于指定的中心点 ( cp )。
  • rectangle.self.move(qr.topLeft()) :此行将小组件移动到矩形 ( qr ) 的左上角。 qr.topLeft() 返回表示矩形左上角的 A QPoint 。
import sys
from PyQt6.QtWidgets import QApplication, QWidget
from PyQt6.QtGui import QScreen, QGuiApplication
from PyQt6.QtGui import QIconclass MyApplication(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setGeometry(0, 0, 300, 200)  # Set window sizeself.setWindowTitle('派森斗罗')self.setWindowIcon(QIcon('logo.png'))self.center()  # Center the window on the screendef center(self):qr=self.frameGeometry()cp=QGuiApplication.primaryScreen().availableGeometry().center()qr.moveCenter(cp)self.move(qr.topLeft())if __name__ == '__main__':app = QApplication(sys.argv)ex = MyApplication()ex.show()sys.exit(app.exec())

PyQt6-初探QMainWindow-各模块的学习方法

QMainWindow是Qt框架中的一个类,用于创建主窗口应用程序。它提供了一个具有一般应用程序框架的主窗口,包括菜单栏、工具栏、状态栏和中央工作区域。
以下是QMainWindow的一些主要特性:

  1. 菜单栏(Menu Bar):QMainWindow允许你添加菜单栏,通过菜单栏你可以创建各种菜单,包括文件、编辑、视图等。
  2. 工具栏(Tool Bar): 你可以在主窗口上添加工具栏,工具栏通常包含一些常用的工具按钮,例如打开、保存、剪切、复制等。
  3. 状态栏(Status Bar):QMainWindow还提供了一个状态栏,用于显示应用程序的状态信息或者当前操作的相关信息。
  4. 中央工作区域(Central Widget): 主要的应用程序界面通常放置在中央工作区域,这是一个可以包含其他Qt小部件的区域,例如文本编辑器、图形视图等。
  5. Dock小部件(Dock Widgets):QMainWindow支持将一些小部件作为停靠窗口,可以通过拖拽将它们放置在主窗口的边缘。
  6. 窗口管理功能: 包括最大化、最小化、关闭等窗口管理功能。

下面是一个简单的例子,演示如何创建一个基本的QMainWindow

from PyQt5.QtWidgets import QApplication, QMainWindow, QLabelclass MyMainWindow(QMainWindow):def __init__(self):super().__init__()# 设置主窗口标题self.setWindowTitle('My Main Window')# 添加标签到中央工作区域central_widget = QLabel("Hello, QMainWindow!")self.setCentralWidget(central_widget)# 添加菜单栏menubar = self.menuBar()file_menu = menubar.addMenu('File')file_menu.addAction('Open')file_menu.addAction('Save')# 添加工具栏toolbar = self.addToolBar('Tools')toolbar.addAction('Cut')toolbar.addAction('Copy')toolbar.addAction('Paste')# 添加状态栏statusbar = self.statusBar()statusbar.showMessage('Ready')if __name__ == '__main__':app = QApplication([])window = MyMainWindow()window.show()app.exec_()

这个例子创建了一个简单的主窗口,包括一个标签作为中央工作区域,一个简单的菜单栏,一个工具栏和一个状态栏。这只是一个入门示例,你可以根据你的应用程序需求自定义和扩展QMainWindow

多页面切换实例

在PyQt6中,可以使用QTabWidgetQWidget来实现多页面切换。
当然你也可以自定义组件来实现这样的功能。在这里我们使用QTabWidgetQWidget
以下是一个简单的示例:

import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QTabWidget, QVBoxLayout, QPushButton, QWidget
from PyQt6.QtGui import QIconclass MainWindow(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("派森斗罗")self.setWindowIcon(QIcon('logo.png'))self.setGeometry(100, 100, 800, 600)self.tab_widget = QTabWidget()self.setCentralWidget(self.tab_widget)self.page1 = QWidget()self.page2 = QWidget()self.tab_widget.addTab(self.page1, "页面1")self.tab_widget.addTab(self.page2, "页面2")layout = QVBoxLayout()button1 = QPushButton("切换到页面2")button1.clicked.connect(lambda: self.switch_page(2))layout.addWidget(button1)button2 = QPushButton("切换到页面1")button2.clicked.connect(lambda: self.switch_page(1))layout.addWidget(button2)self.page1.setLayout(layout)self.page2.setLayout(layout)def switch_page(self, index):self.tab_widget.setCurrentIndex(index - 1)if __name__ == "__main__":app = QApplication(sys.argv)mainWin = MainWindow()mainWin.show()sys.exit(app.exec())

在这个示例中,我们创建了一个QMainWindow,并设置了一个QTabWidget作为其中心部件。然后,我们创建了两个QWidgetpage1page2),并将它们添加到QTabWidget中。我们还添加了两个按钮,分别用于在两个页面之间切换。当点击这些按钮时,会调用switch_page方法来切换当前选中的页面。

import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QTabWidget, QVBoxLayout, QPushButton, QWidget,QStackedWidget,QLabel
from PyQt6.QtGui import QIconclass MainWindow(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("派森斗罗")self.setWindowIcon(QIcon('logo.png'))self.setGeometry(100, 100, 800, 600)self.initStackWeight()self.initTabWeight()def initStackWeight(self):self.stacked_widget = QStackedWidget()page1 = QWidget()page2 = QWidget()label1 = QLabel('这是页面 1')label2 = QLabel('这是页面 2')page1.layout = QVBoxLayout(page1)page2.layout = QVBoxLayout(page2)page1.layout.addWidget(label1)page2.layout.addWidget(label2)self.stacked_widget.addWidget(page1)self.stacked_widget.addWidget(page2)button1 = QPushButton('显示页面 1')button1.clicked.connect(lambda: self.stacked_widget.setCurrentIndex(0))button2 = QPushButton('显示页面 2')button2.clicked.connect(lambda: self.stacked_widget.setCurrentIndex(1))# 显示按钮和堆栈式布局mainWindow=QWidget()layout = QVBoxLayout()layout.addWidget(button1)layout.addWidget(button2)layout.addWidget(self.stacked_widget)mainWindow.setLayout(layout)self.setCentralWidget(mainWindow)def initTabWeight(self):self.tab_widget = QTabWidget()print(self.stacked_widget.widget(1).layout.addWidget(self.tab_widget))self.page1 = QWidget()self.page2 = QWidget()self.tab_widget.addTab(self.page1, "页面1")self.tab_widget.addTab(self.page2, "页面2")layout1 = QVBoxLayout()button1 = QPushButton("切换到标签页2")button1.clicked.connect(lambda: self.switch_page(2))layout1.addWidget(button1)self.page1.setLayout(layout1)layout2 = QVBoxLayout()button2 = QPushButton("切换到标签页1")button2.clicked.connect(lambda: self.switch_page(1))layout2.addWidget(button2)self.page2.setLayout(layout2)def switch_page(self, index):self.tab_widget.setCurrentIndex(index - 1)if __name__ == "__main__":app = QApplication(sys.argv)mainWin = MainWindow()mainWin.show()sys.exit(app.exec())

顶部菜单栏实例

from PyQt6.QtWidgets import QApplication, QMainWindow, QMenu, QMenuBar
from PyQt6.QtGui import QIcon,QAction
from PyQt6.QtCore import Qtclass MainWindow(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):menubar = self.menuBar()# 创建文件菜单,里面有二级菜单:打开,保存,设置fileMenu = menubar.addMenu('文件')openFile = QAction(QIcon('./assets/imgs/icons/open-file.png'),'打开文件', self)openFile.setShortcut('Ctrl+O')openFile.triggered.connect(self.openFile)fileMenu.addAction(openFile)openFolder = QAction(QIcon('./assets/imgs/icons/open-folder.png'),'打开文件夹', self)openFolder.triggered.connect(self.openFolder)fileMenu.addAction(openFolder)fileMenu.addSeparator()saveFile = QAction(QIcon('./assets/imgs/icons/save.png'),'保存', self)saveFile.setShortcut('Ctrl+S')saveFile.triggered.connect(self.saveFile)fileMenu.addAction(saveFile)setting = QAction(QIcon('./assets/imgs/icons/setting.png'),'设置', self)setting.triggered.connect(self.setting)fileMenu.addAction(setting)# 创建帮助菜单helpMenu = menubar.addMenu('帮助')about = QAction(QIcon('./assets/imgs/icons/about.png'),'关于', self)about.triggered.connect(self.about)helpMenu.addAction(about)helpMenu.addSeparator()donation = QAction(QIcon('./assets/imgs/icons/donation.png'),'捐赠', self)donation.triggered.connect(self.donation)helpMenu.addAction(donation)self.setWindowTitle("派森斗罗")self.setWindowIcon(QIcon('logo.png'))self.setGeometry(300, 300, 400, 200)self.show()def openFile(self):print('打开文件')def openFolder(self):print('打开文件夹')def setting(self):print('设置')def saveFile(self):print('保存文件')def about(self):print('这是一个顶部菜单栏示例程序')def donation(self):print('捐赠选项')if __name__ == '__main__':app = QApplication([])window = MainWindow()app.exec()

多种栏示例

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow,QPushButton,QLabel, QToolBar, QStatusBar, QTabWidget, QVBoxLayout, QWidget
from PyQt6.QtGui import QAction,QIconclass MyApplication(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):# 创建一个退出动作exitAction = QAction('退出', self)exitAction.setShortcut('Ctrl+Q')exitAction.triggered.connect(self.close)# 创建一个新建动作newAction = QAction('新建', self)# 创建一个打开动作openAction = QAction('打开', self)# 创建菜单栏menubar = self.menuBar()fileMenu = menubar.addMenu('文件')fileMenu.addAction(newAction)fileMenu.addAction(openAction)fileMenu.addSeparator()fileMenu.addAction(exitAction)# 创建工具栏toolbar = QToolBar()toolbar.addAction(newAction)toolbar.addAction(openAction)toolbar.addAction(exitAction)self.addToolBar(toolbar)# 创建状态栏statusbar = QStatusBar()self.setStatusBar(statusbar)statusbar.showMessage('这是状态栏',1000)btn=QPushButton('显示消息',self)btn.move(100,0)# 查看定义类btn.clicked.connect(lambda x:statusbar.showMessage('您好~',1000))# 创建标签栏tab_widget = QTabWidget()tab1 = QWidget()tab2 = QWidget()tab_widget.addTab(tab1, '标签1')tab_widget.addTab(tab2, '标签2')layout = QVBoxLayout()tab1.setLayout(layout)layout.addWidget(QWidget())  # 向标签1添加内容self.setCentralWidget(tab_widget)# 创建侧栏sidebar = QToolBar('侧栏')sidebar.addWidget(QLabel('这是侧边栏'))  # 向侧栏添加内容self.addToolBar(sidebar)# 创建工具箱栏toolbox = QToolBar('工具箱')toolbox.addWidget(QLabel('这是工具箱'))  # 向工具箱添加内容self.addToolBar(toolbox)# 设置主窗口属性self.setGeometry(100, 100, 600, 400)self.setWindowTitle('派森斗罗')self.setWindowIcon(QIcon('logo.png'))self.show()if __name__ == '__main__':app = QApplication(sys.argv)ex = MyApplication()sys.exit(app.exec())

左侧菜单控制右侧多页面切换

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QHBoxLayout, QListWidget, QWidget, QStackedWidget,QLabel,QListWidgetItem
from PyQt6.QtGui import QIcon,QAction
from PyQt6.QtCore import Qtclass MyApplication(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setGeometry(100, 100, 800, 600)self.setWindowTitle('多页面切换示例')# 创建一个主窗口部件central_widget = QWidget()self.setCentralWidget(central_widget)# 创建左侧导航栏nav_list = QListWidget()nav_list.addItem(QListWidgetItem(QIcon('./assets/imgs/icons/game.svg'),'游戏'))nav_list.addItem(QListWidgetItem(QIcon('./assets/imgs/icons/login.png'),'登录'))nav_list.addItem(QListWidgetItem(QIcon('./assets/imgs/icons/setting.png'),'设置'))nav_list.setFixedWidth(100)# nav_list.setViewMode(QListWidget.IconMode)nav_list.currentItemChanged.connect(self.switchPage)# 创建右侧多页面容器page_container = QStackedWidget()page1 = QWidget()QLabel('这是页面 1',page1)page1.setWindowTitle('页面 1')page2 = QWidget()page2.setWindowTitle('页面 2')QLabel('这是页面 2',page2)page_container.addWidget(page1)page_container.addWidget(page2)# page_container.setFixedWidth(500)# 创建布局管理器layout = QHBoxLayout()layout.addWidget(nav_list)layout.addWidget(page_container)central_widget.setLayout(layout)def switchPage(self, current, previous):if current:selected_index = self.centralWidget().layout().itemAt(0).widget().currentRow()self.centralWidget().layout().itemAt(1).widget().setCurrentIndex(selected_index)if __name__ == '__main__':app = QApplication(sys.argv)ex = MyApplication()ex.show()sys.exit(app.exec())

pyqt6中如何实现多页面切换?

在 PyQt6 中实现多页面切换通常有多种方法,其中两种主要方法是使用 QStackedWidgetQTabWidget。以下是如何使用这两种方法实现多页面切换的总结:

  1. 使用 QStackedWidget
    • 创建一个 QStackedWidget 对象来托管多个页面。
    • 为每个页面创建一个独立的 QWidget 子类,包括该页面的内容和控件。
    • 使用 addWidget 方法将这些页面部件添加到 QStackedWidget 中,每个页面都有一个索引。
    • 使用 setCurrentIndex 方法切换页面,通过指定页面的索引。
    • 适用于需要程序控制多页面切换的情况。

示例代码:

stacked_widget = QStackedWidget()
page1 = QWidget()
page2 = QWidget()
stacked_widget.addWidget(page1)
stacked_widget.addWidget(page2)
stacked_widget.setCurrentIndex(0)  # 切换到第一个页面
  1. 使用 QTabWidget
    • 创建一个 QTabWidget 对象,它提供了选项卡式的多页面切换。
    • 为每个标签页创建一个独立的 QWidget 子类,包括页面的内容和控件。
    • 使用 addTab 方法将这些页面部件添加到 QTabWidget,同时指定标签页的标题。
    • 用户可以通过点击标签页来切换页面。
    • 适用于以选项卡形式显示多个页面的情况。

示例代码:

tab_widget = QTabWidget()
tab1 = QWidget()
tab2 = QWidget()
tab_widget.addTab(tab1, "页面 1")
tab_widget.addTab(tab2, "页面 2")

根据您的项目需求和个人喜好,您可以选择使用其中一种或两种方法来实现多页面切换。无论您选择哪种方法,都可以根据需要自定义和扩展页面的内容。

QTabweight与Qstackweight的区别

在 PyQt 中,QTabWidgetQStackedWidget 是用于处理多页面(或多视图)的两个不同的部件。它们有一些区别,主要在于它们的设计和用途。

QTabWidget:

  1. 标签页式布局: QTabWidget 提供了一个标签页式的用户界面,允许用户通过选项卡(标签页)来切换不同的页面。
  2. 导航和可见性: 用户可以通过点击选项卡切换页面。每个选项卡上通常有一个相关的标题,并且用户可以通过点击标题来选择相应的页面。
  3. 集成标签栏: QTabWidget 自动提供了一个标签栏,用于容纳选项卡。标签栏通常位于部件的顶部。
  4. 适用于多个页面场景: 当您有一组相关的页面,希望以标签页的形式进行切换时,QTabWidget 是一个很好的选择。
from PyQt6.QtWidgets import QApplication, QWidget, QTabWidget, QVBoxLayout, QLabelapp = QApplication([])# 创建 QTabWidget
tab_widget = QTabWidget()# 添加标签页
tab_page1 = QWidget()
label1 = QLabel('这是标签页 1')
tab_page1.layout = QVBoxLayout(tab_page1)
tab_page1.layout.addWidget(label1)
tab_page1.setLayout(tab_page1.layout)
tab_widget.addTab(tab_page1, '标签页 1')tab_page2 = QWidget()
label2 = QLabel('这是标签页 2')
tab_page2.layout = QVBoxLayout(tab_page2)
tab_page2.layout.addWidget(label2)
tab_page2.setLayout(tab_page2.layout)
tab_widget.addTab(tab_page2, '标签页 2')tab_widget.show()
app.exec()

QStackedWidget:

  1. 堆栈式布局: QStackedWidget 提供了一个堆栈式的用户界面,允许用户通过推入和弹出页面来切换。
  2. 程序控制切换: 切换页面通常是由程序控制的,而不是用户通过点击标签页来触发的。
  3. 没有集成标签栏: QStackedWidget 不提供内置的标签栏。相反,您需要使用其他部件(例如按钮、菜单)来触发页面切换。
  4. 适用于单个页面显示: 当您有多个页面,但同一时间只显示其中一个页面时,QStackedWidget 是一个很好的选择。
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QPushButton, QStackedWidgetapp = QApplication([])# 创建 QStackedWidget
stacked_widget = QStackedWidget()# 添加页面
page1 = QWidget()
label1 = QLabel('这是页面 1')
page1.layout = QVBoxLayout(page1)
page1.layout.addWidget(label1)
page1.setLayout(page1.layout)
stacked_widget.addWidget(page1)page2 = QWidget()
label2 = QLabel('这是页面 2')
page2.layout = QVBoxLayout(page2)
page2.layout.addWidget(label2)
page2.setLayout(page2.layout)
stacked_widget.addWidget(page2)# 创建按钮用于切换页面
button1 = QPushButton('显示页面 1')
button1.clicked.connect(lambda: stacked_widget.setCurrentIndex(0))button2 = QPushButton('显示页面 2')
button2.clicked.connect(lambda: stacked_widget.setCurrentIndex(1))# 显示按钮和堆栈式布局
layout = QVBoxLayout()
layout.addWidget(button1)
layout.addWidget(button2)
layout.addWidget(stacked_widget)# 设置堆栈式布局为窗口布局
window = QWidget()
window.setLayout(layout)
window.show()app.exec()

总体而言,QTabWidget 适用于标签页式导航,而 QStackedWidget 适用于以堆栈形式切换页面的场景。您可以根据具体需求选择使用哪一个。

Qframe与Qweight的区别

在 PyQt 中,QFrameQWidget 是两个不同的类,它们用于创建界面上的可视化组件,但有一些区别。

  1. **QFrame**** 类:**
    • QFrameQWidget 的子类,因此 QFrame 可以包含在其他 QWidget 内或作为 QMainWindow 的中心部件。
    • QFrame 是一个简单的容器,通常用于包含其他小部件或进行布局管理。
    • QFrame 通常用于创建矩形框架,比如创建边框、背景或者一些特殊的辅助图形元素。
from PyQt6.QtWidgets import QFrame
frame = QFrame()
  1. **QWidget**** 类:**
    • QWidget 是一个通用的用户界面对象,也是 QFrame 的基类。
    • QWidget 通常用于创建应用程序的主窗口或作为主窗口中的中心部件。
    • QFrame 相比,QWidget 是更通用的界面元素,可以包含其他小部件,并提供更多的功能。
from PyQt6.QtWidgets import QWidget
widget = QWidget()

总的来说,QFrame 更专注于创建框架和辅助图形,而 QWidget 是一个更通用的界面元素,可以包含其他小部件并提供更广泛的功能。在实际使用中,你可以根据需求选择使用 QWidgetQFrame

先显示登陆页面,登陆成功后显示主页面

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QPushButton, QLabel
from PyQt6 import QtCore
from PyQt6.QtGui import QIconclass LoginWindow(QWidget):loginSuccessSignal = QtCore.pyqtSignal()  # 登录成功的信号def __init__(self):super().__init__()self.initUI()def initUI(self):layout = QVBoxLayout(self)self.username_input = QLineEdit(self)self.password_input = QLineEdit(self)self.password_input.setEchoMode(QLineEdit.EchoMode.Password)login_button = QPushButton('Login', self)login_button.clicked.connect(self.login)layout.addWidget(QLabel('Username:'))layout.addWidget(self.username_input)layout.addWidget(QLabel('Password:'))layout.addWidget(self.password_input)layout.addWidget(login_button)self.setGeometry(300, 300, 400, 200)self.setWindowTitle('Login Window')def login(self):# 在实际应用中,这里应该有登录验证的逻辑# 这里简化为判断用户名和密码是否为正确if self.username_input.text() == '1' and self.password_input.text() == '1':self.loginSuccessSignal.emit()  # 发送登录成功信号self.close()class YourMainWindow(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.login_window = LoginWindow()self.login_window.loginSuccessSignal.connect(self.showMainWindow)def showMainWindow(self):self.setGeometry(300, 300, 400, 200)self.setWindowTitle('派森斗罗')self.setWindowIcon(QIcon('logo.png'))self.show()if __name__ == '__main__':app = QApplication(sys.argv)main_window = YourMainWindow()main_window.login_window.show()sys.exit(app.exec())

窗口渐显与渐隐

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
from PyQt6.QtCore import QPropertyAnimationclass FadeWindow(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setGeometry(300, 300, 400, 200)self.setWindowTitle('派森斗罗')layout = QVBoxLayout(self)fade_out_button = QPushButton('Fade Out', self)fade_out_button.clicked.connect(self.fadeOut)fade_in_button = QPushButton('Fade In', self)fade_in_button.clicked.connect(self.fadeIn)layout.addWidget(fade_out_button)layout.addWidget(fade_in_button)# Set initial opacity to 0self.setWindowOpacity(0.0)self.fadeIn()def fadeIn(self):self.animation = QPropertyAnimation(self, b"windowOpacity")self.animation.setStartValue(0.0)self.animation.setEndValue(1.0)self.animation.setDuration(1000)self.animation.start()def fadeOut(self):self.animation = QPropertyAnimation(self, b"windowOpacity")self.animation.setStartValue(1.0)self.animation.setEndValue(0.0)self.animation.setDuration(1000)self.animation.finished.connect(self.close)self.animation.start()if __name__ == '__main__':app = QApplication(sys.argv)fade_window = FadeWindow()fade_window.show()sys.exit(app.exec())

窗口居中变大出现

我最开始想的是从小变到大,绘制之后再不断调用居中函数,最后发现窗口在左上角和中间不断闪动,于是我认真思考了一下想到了其实可以计算出初始状态和末状态的位置大小信息。
如何查看QPropertyAnimation类的方法以及信号。
可以优化一下出场,免去最开始的闪烁一下。

import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
from PyQt6.QtCore import QPropertyAnimation, QEasingCurve,QRect
from PyQt6.QtGui import QGuiApplicationclass ScaleWindow(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):# self.setGeometry(300, 300, 200, 100)self.setWindowTitle('变大窗口')self.scaleIn()def scaleIn(self):self.animation = QPropertyAnimation(self, b"geometry")self.animation.setStartValue(QRect(100,100,0,0))self.animation.setEndValue(QRect(100,100,200,300))self.animation.setDuration(1000)self.animation.valueChanged.connect(self.center)self.animation.setEasingCurve(QEasingCurve.Type.OutQuad)  # Use QEasingCurve.Type.OutQuadself.animation.start()def center(self):self.hide()qr=self.frameGeometry()cp=QGuiApplication.primaryScreen().availableGeometry().center()qr.moveCenter(cp)self.move(qr.topLeft())self.show()if __name__ == '__main__':app = QApplication(sys.argv)scale_window = ScaleWindow()scale_window.show()sys.exit(app.exec())
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
from PyQt6.QtCore import QPropertyAnimation, QEasingCurve,QRect
from PyQt6.QtGui import QGuiApplicationclass ScaleWindow(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setGeometry(0, 0, 800, 600)self.setWindowTitle('变大窗口')self.center()self.scaleIn()def scaleIn(self):cp=QGuiApplication.primaryScreen().availableGeometry().center()qr=self.frameGeometry()self.animation = QPropertyAnimation(self, b"geometry")self.animation.setStartValue(QRect(cp.x(),cp.y(),0,0))self.animation.setEndValue(qr)self.animation.setDuration(1000)# self.animation.setDuration(3000)self.animation.setEasingCurve(QEasingCurve.Type.Linear)# self.animation.setEasingCurve(QEasingCurve.Type.OutQuint)# self.animation.setEasingCurve(QEasingCurve.Type.OutBack)# self.animation.setEasingCurve(QEasingCurve.Type.OutElastic)self.animation.start()def center(self):qr=self.frameGeometry()cp=QGuiApplication.primaryScreen().availableGeometry().center()qr.moveCenter(cp)self.move(qr.topLeft())if __name__ == '__main__':app = QApplication(sys.argv)scale_window = ScaleWindow()scale_window.show()sys.exit(app.exec())
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
from PyQt6.QtCore import QPropertyAnimation, QEasingCurve,QRect
from PyQt6.QtGui import QGuiApplicationclass ScaleWindow(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setWindowTitle('变大窗口')self.scaleIn()def scaleIn(self):cp=QGuiApplication.primaryScreen().availableGeometry().center()qr=self.center()self.animation = QPropertyAnimation(self, b"geometry")self.animation.setStartValue(QRect(cp.x(),cp.y(),0,0))self.animation.setEndValue(qr)self.animation.setDuration(1000)# self.animation.setDuration(3000)self.animation.setEasingCurve(QEasingCurve.Type.Linear)# self.animation.setEasingCurve(QEasingCurve.Type.OutQuint)# self.animation.setEasingCurve(QEasingCurve.Type.OutBack)# self.animation.setEasingCurve(QEasingCurve.Type.OutElastic)self.animation.start()def center(self):qr=QRect(0, 0, 800, 600)cp=QGuiApplication.primaryScreen().availableGeometry().center()qr.moveCenter(cp)return qrif __name__ == '__main__':app = QApplication(sys.argv)scale_window = ScaleWindow()scale_window.show()sys.exit(app.exec())

最小化窗口到托盘,右键菜单,窗口恢复

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QSystemTrayIcon, QMenu
from PyQt6.QtGui import QIcon, QActionclass MyWindow(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setWindowTitle('PyQt6 托盘示例')self.setWindowIcon(QIcon('logo.png'))self.setGeometry(300, 300, 300, 200)# 创建系统托盘图标self.tray_icon = QSystemTrayIcon(self)self.tray_icon.setIcon(QIcon('logo.png'))# 创建托盘图标菜单tray_menu = QMenu(self)action1 = tray_menu.addAction('设置一')action2 = tray_menu.addAction('设置二')tray_menu.addSeparator()action3 = tray_menu.addAction('打开主面板(未实现)')tray_menu.addSeparator()restore_action = QAction(QIcon('./assets/imgs/icons/recover.svg'),'还原', self)restore_action.triggered.connect(self.showNormal)exit_action = QAction(QIcon('./assets/imgs/icons/quit.svg'),'退出', self)exit_action.triggered.connect(app.quit)tray_menu.addAction(restore_action)tray_menu.addAction(exit_action)self.tray_icon.setContextMenu(tray_menu)# 托盘图标点击事件self.tray_icon.activated.connect(self.tray_icon_activated)self.tray_icon.show()# self.tray_icon.showMessage("托盘图标示例", "程序已最小化到托盘")def tray_icon_activated(self, reason):if reason == QSystemTrayIcon.ActivationReason.Trigger:if self.isHidden():self.showNormal()self.raise_()def closeEvent(self, event):# 重写窗口关闭事件,实现最小化到托盘event.ignore()self.hide()if __name__ == '__main__':app = QApplication(sys.argv)window = MyWindow()window.show()sys.exit(app.exec())

背景运动及模糊滤镜

Steam登陆界面复现-PyQt6-Python-运动背景图三种实现方式

最开始使用的是重写paintEvent方法,但是后来发现加上模糊的时候窗口内容也模糊了。使用QLabel堆叠实现背景就不会造成窗口内容也模糊了。

import sys
from PyQt6.QtCore import Qt, QTimer
from PyQt6.QtGui import QPainter, QPixmap
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget,QGraphicsBlurEffect,QLabelclass MovingBackgroundWidget(QWidget):def __init__(self):super().__init__()self.setGeometry(100, 100, 800, 600)self.initBg()self.initUI()def initUI(self):label = QLabel('啊哈哈哈哈哈', self)label.setGeometry(100, 100, 100, 30)def initBg(self):# 设置背景图片self.background_pixmap = QPixmap("bg.jpg")# 暂存当前现实背景图片self.background_pixmap_tmp=QPixmap("bg.jpg")self.tmp_x=0self.tmp_y=0# 设置定时器,每隔一段时间触发重绘事件self.bg_timer = QTimer(self)self.bg_timer.timeout.connect(self.update_background)self.bg_timer.start(50)  # 调整移动速度,单位为毫秒# 添加毛玻璃模糊滤镜blur_effect = QGraphicsBlurEffect()blur_effect.setBlurRadius(10)self.setGraphicsEffect(blur_effect)def paintEvent(self, event):painter = QPainter(self)painter.drawPixmap(0, 0, self.background_pixmap_tmp)def update_background(self):self.tmp_x+=2self.tmp_y+=1self.background_pixmap_tmp = self.background_pixmap.copy(self.tmp_x, self.tmp_y,self.background_pixmap.width()-self.tmp_x, self.background_pixmap.height()-self.tmp_y)# 强制重绘self.update()if __name__ == "__main__":app = QApplication(sys.argv)widget = MovingBackgroundWidget()# 将 widget 设置为主窗口的中央部件main_window = QMainWindow()main_window.setCentralWidget(widget)main_window.setGeometry(100, 100, 800, 600)main_window.show()sys.exit(app.exec())
import sys
from PyQt6.QtCore import Qt, QTimer
from PyQt6.QtGui import QPainter, QPixmap,QFont
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget,QLabel,QGraphicsBlurEffect,QHBoxLayout,QVBoxLayout)
from PyQt6.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QGridLayout, QCheckBox, QGraphicsOpacityEffect
from PyQt6.QtCore import Qt, QRect, QPropertyAnimation, QParallelAnimationGroup,QSize
from PyQt6.QtGui import QPixmap, QMovie
class LoginWidget(QWidget):def __init__(self):super().__init__()self.setFixedSize(880,550)self.setWindowFlag(Qt.WindowType.FramelessWindowHint,True)# self.initStyle()self.initBg()self.initUI()def initUI(self):# 创建布局和部件main_layout = QVBoxLayout(self)close_layout = QHBoxLayout()top_layout = QHBoxLayout()center_layout = QVBoxLayout()bottom_layout=QHBoxLayout()logo_label = QLabel(self)logo_pixmap = QPixmap("logo.png").scaled(70,70)logo_label.setPixmap(logo_pixmap)logo_label.setAlignment(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignLeft)software_label = QLabel("派森斗罗", self)software_label.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter)software_label.setStyleSheet("font-size: 20px; font-weight: bold; color: white;")close_button = QPushButton("×", self)close_button.setFixedSize(50,50)close_button.setStyleSheet("QPushButton {background-color: rgba(0, 0, 0, 0); color: #616F77;font-size:25px;}\QPushButton:hover {background-color: #E22A27; color: white;}")close_button.clicked.connect(self.close)username_label = QLabel("账号:", self)password_label = QLabel("密码:", self)username_label.setStyleSheet("color:white;font-weight:bold;font-size:15px;")password_label.setStyleSheet("color:white;font-weight:bold;font-size:15px;")username_input = QLineEdit(self)password_input = QLineEdit(self)username_input.setFixedSize(180,30)password_input.setFixedSize(180,30)username_input.setStyleSheet("QLineEdit{border:0;background-color:rgba(0, 0, 0, 100);padding:5px;color:white;font-weight:bold;}\QLineEdit:hover{background-color:rgba(0, 0, 0, 50);}")password_input.setEchoMode(QLineEdit.EchoMode.Password)password_input.setStyleSheet("QLineEdit{border:0;background-color:rgba(0, 0, 0, 100);padding:5px;color:white;font-weight:bold;}\QLineEdit:hover{background-color:rgba(0, 0, 0, 50);}")remember_me_checkbox = QCheckBox("记住密码", self)remember_me_checkbox.setStyleSheet("color:white;")login_button = QPushButton("登录", self)login_button.setFixedSize(100,25)login_button.setStyleSheet("QPushButton{border:0;color:white;background-color:rgba(0, 0, 255, 150);font-weight:bold;}\QPushButton:hover{background-color:rgba(0, 0, 255, 80);}")login_button.clicked.connect(lambda x:print('登录'))register_label = QLabel("还没有账号?  ", self)register_label.setStyleSheet("color:white;")register_button = QPushButton("去注册", self)font=register_button.font()font.setUnderline(True)register_button.setFont(font)register_button.setStyleSheet("border:0;color:white;")register_button.clicked.connect(lambda x:print('注册'))# 添加部件到布局close_layout.addStretch(1)close_layout.addWidget(close_button)top_layout.addWidget(logo_label)top_layout.addWidget(software_label)top_layout.addStretch(1)center_layout.addWidget(username_label)center_layout.addWidget(username_input)center_layout.addWidget(password_label)center_layout.addWidget(password_input)center_layout.addWidget(remember_me_checkbox)center_layout.addWidget(login_button, alignment=Qt.AlignmentFlag.AlignCenter)center_layout.setAlignment(Qt.AlignmentFlag.AlignHCenter|Qt.AlignmentFlag.AlignVCenter)bottom_layout.addStretch(10)bottom_layout.addWidget(register_label)bottom_layout.addWidget(register_button)bottom_layout.addStretch(1)main_layout.addLayout(close_layout)main_layout.addLayout(top_layout)main_layout.addStretch(1)main_layout.addLayout(center_layout)main_layout.addStretch(5)main_layout.addLayout(bottom_layout)main_layout.addStretch(3)def mousePressEvent(self, event):# 鼠标按压if event.button() == Qt.MouseButton.LeftButton and self.geometry().contains(self.mapToGlobal(event.pos())):self.dis = self.mapToGlobal(event.pos()) - self.pos()self.dragging = Trueself.setCursor(Qt.CursorShape.ClosedHandCursor)def mouseMoveEvent(self, event):# 鼠标移动的时候判断是否是拖拽状态,如果是的话就移动窗口if self.dragging:self.move(self.mapToGlobal(event.pos()) - self.dis)def mouseReleaseEvent(self, event):# 鼠标释放的时候接触拖拽状态并且改变鼠标样式if event.button() == Qt.MouseButton.LeftButton and self.dragging:self.dragging = Falseself.setCursor(Qt.CursorShape.OpenHandCursor)def initStyle(self):self.font=QFont('./assets/fonts/1.ttf')self.font.setPointSize(32)self.font.setBold(True)self.font.setStyle(QFont.Style.StyleNormal)def initBg(self):self.bg_label=QLabel(self)# 设置背景图片self.background_pixmap = QPixmap("bg1.jpg").scaled(880+500,550+250)# 暂存当前现实背景图片self.background_pixmap_tmp=QPixmap("bg1.jpg")self.tmp_x=0self.tmp_y=0self.dx=2self.dy=1# 设置定时器,每隔一段时间触发重绘事件self.bg_timer = QTimer(self)self.bg_timer.timeout.connect(self.update_background)self.bg_timer.start(50)  # 调整移动速度,单位为毫秒# 添加毛玻璃模糊滤镜blur_effect = QGraphicsBlurEffect()blur_effect.setBlurRadius(20)self.bg_label.setGraphicsEffect(blur_effect)def update_background(self):self.bg_label.setGeometry(self.rect())self.bg_label.setPixmap(self.background_pixmap_tmp)if self.tmp_x<0 or self.tmp_x>self.background_pixmap.width()-880:self.dx,self.dy=-self.dx,-self.dyself.tmp_x+=self.dxself.tmp_y+=self.dyself.background_pixmap_tmp = self.background_pixmap.copy(self.tmp_x,self.background_pixmap.height()-550-self.tmp_y,880,550)if __name__ == "__main__":app = QApplication(sys.argv)widget = LoginWidget()widget.show()sys.exit(app.exec())
from PyQt6.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QGridLayout, QCheckBox, QGraphicsOpacityEffect
from PyQt6.QtCore import Qt, QRect, QPropertyAnimation, QParallelAnimationGroup,QSize
from PyQt6.QtGui import QPixmap, QMovie
class LoginWindow(QWidget):def __init__(self):super().__init__()self.setWindowTitle("Login")        self.initBg()self.initUI()def mousePressEvent(self, event):# 鼠标按压,判断是否是鼠标左键并且点击点在窗口内if event.button() == Qt.MouseButton.LeftButton and self.geometry().contains(self.mapToGlobal(event.pos())):self.dis = self.mapToGlobal(event.pos()) - self.pos()print(self.mapToGlobal(event.pos()),event.pos(),self.pos(),self.dis)self.dragging = Trueself.setCursor(Qt.CursorShape.ClosedHandCursor)def mouseMoveEvent(self, event):# 鼠标移动的时候判断是否是拖拽状态,如果是的话就移动窗口if self.dragging:# self.move(event.pos()-self.dis)self.move(self.mapToGlobal(event.pos()) - self.dis)def mouseReleaseEvent(self, event):# 鼠标释放的时候接触拖拽状态并且改变鼠标样式if event.button() == Qt.MouseButton.LeftButton and self.dragging:self.dragging = Falseself.setCursor(Qt.CursorShape.OpenHandCursor)def initBg(self):# 设置背景图片self.setFixedSize(880, 550)background_label = QLabel(self)background_label.setGeometry(self.rect())movie = QMovie("./assets/imgs/bg/bg.gif")movie.setScaledSize(QSize(880,550))background_label.setMovie(movie)movie.start()def initUI(self):self.setWindowFlag(Qt.WindowType.FramelessWindowHint)# 创建布局和部件main_layout = QVBoxLayout(self)close_layout = QHBoxLayout()top_layout = QHBoxLayout()center_layout = QVBoxLayout()bottom_layout=QHBoxLayout()logo_label = QLabel(self)logo_pixmap = QPixmap("logo.png").scaled(70,70)logo_label.setPixmap(logo_pixmap)logo_label.setAlignment(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignLeft)software_label = QLabel("派森斗罗", self)software_label.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter)software_label.setStyleSheet("font-size: 20px; font-weight: bold; color: white;")close_button = QPushButton("×", self)close_button.setFixedSize(50,50)close_button.setStyleSheet("QPushButton {background-color: rgba(0, 0, 0, 0); color: #616F77;font-size:25px;}\QPushButton:hover {background-color: #E22A27; color: white;}")close_button.clicked.connect(self.close)username_label = QLabel("账号:", self)password_label = QLabel("密码:", self)username_label.setStyleSheet("color:white;font-weight:bold;font-size:15px;")password_label.setStyleSheet("color:white;font-weight:bold;font-size:15px;")username_input = QLineEdit(self)password_input = QLineEdit(self)username_input.setFixedSize(180,30)password_input.setFixedSize(180,30)username_input.setStyleSheet("QLineEdit{border:0;background-color:rgba(0, 0, 0, 100);padding:5px;color:white;font-weight:bold;}\QLineEdit:hover{background-color:rgba(0, 0, 0, 50);}")password_input.setEchoMode(QLineEdit.EchoMode.Password)password_input.setStyleSheet("QLineEdit{border:0;background-color:rgba(0, 0, 0, 100);padding:5px;color:white;font-weight:bold;}\QLineEdit:hover{background-color:rgba(0, 0, 0, 50);}")remember_me_checkbox = QCheckBox("记住密码", self)remember_me_checkbox.setStyleSheet("color:white;")login_button = QPushButton("登录", self)login_button.setFixedSize(100,25)login_button.setStyleSheet("QPushButton{border:0;color:white;background-color:rgba(0, 0, 255, 150);font-weight:bold;}\QPushButton:hover{background-color:rgba(0, 0, 255, 80);}")login_button.clicked.connect(lambda x:print('登录'))register_label = QLabel("还没有账号?  ", self)register_label.setStyleSheet("color:white;")register_button = QPushButton("去注册", self)font=register_button.font()font.setUnderline(True)register_button.setFont(font)register_button.setStyleSheet("border:0;color:white;")register_button.clicked.connect(lambda x:print('注册'))# 添加部件到布局close_layout.addStretch(1)close_layout.addWidget(close_button)top_layout.addWidget(logo_label)top_layout.addWidget(software_label)top_layout.addStretch(1)center_layout.addWidget(username_label)center_layout.addWidget(username_input)center_layout.addWidget(password_label)center_layout.addWidget(password_input)center_layout.addWidget(remember_me_checkbox)center_layout.addWidget(login_button, alignment=Qt.AlignmentFlag.AlignCenter)center_layout.setAlignment(Qt.AlignmentFlag.AlignHCenter|Qt.AlignmentFlag.AlignVCenter)bottom_layout.addStretch(10)bottom_layout.addWidget(register_label)bottom_layout.addWidget(register_button)bottom_layout.addStretch(1)main_layout.addLayout(close_layout)main_layout.addLayout(top_layout)main_layout.addStretch(1)main_layout.addLayout(center_layout)main_layout.addStretch(5)main_layout.addLayout(bottom_layout)main_layout.addStretch(3)if __name__ == '__main__':app = QApplication([])login_window = LoginWindow()login_window.show()app.exec()

窗口自定义拖拽功能

def mousePressEvent(self, event):# 鼠标按压,判断是否是鼠标左键并且点击点在窗口内if event.button() == Qt.MouseButton.LeftButton and self.geometry().contains(self.mapToGlobal(event.pos())):self.dis = self.mapToGlobal(event.pos()) - self.pos()print(self.mapToGlobal(event.pos()),event.pos(),self.pos(),self.dis)self.dragging = Trueself.setCursor(Qt.CursorShape.ClosedHandCursor)
def mouseMoveEvent(self, event):# 鼠标移动的时候判断是否是拖拽状态,如果是的话就移动窗口if self.dragging:# self.move(event.pos()-self.dis)self.move(self.mapToGlobal(event.pos()) - self.dis)
def mouseReleaseEvent(self, event):# 鼠标释放的时候接触拖拽状态并且改变鼠标样式if event.button() == Qt.MouseButton.LeftButton and self.dragging:self.dragging = Falseself.setCursor(Qt.CursorShape.OpenHandCursor)
import sys
from PyQt6.QtWidgets import QApplication, QWidget
from PyQt6.QtGui import QScreen, QGuiApplication,QIcon
from PyQt6.QtCore import Qt, QRect, QPropertyAnimation, QParallelAnimationGroup,QSize
class MyApplication(QWidget):def __init__(self):super().__init__()self.initUI()def mousePressEvent(self, event):# 鼠标按压,判断是否是鼠标左键并且点击点在窗口内if event.button() == Qt.MouseButton.LeftButton and self.geometry().contains(self.mapToGlobal(event.pos())):self.dis = self.mapToGlobal(event.pos()) - self.pos()print(self.mapToGlobal(event.pos()),event.pos(),self.pos(),self.dis)self.dragging = Trueself.setCursor(Qt.CursorShape.ClosedHandCursor)def mouseMoveEvent(self, event):# 鼠标移动的时候判断是否是拖拽状态,如果是的话就移动窗口if self.dragging:# self.move(event.pos()-self.dis)self.move(self.mapToGlobal(event.pos()) - self.dis)def mouseReleaseEvent(self, event):# 鼠标释放的时候接触拖拽状态并且改变鼠标样式if event.button() == Qt.MouseButton.LeftButton and self.dragging:self.dragging = Falseself.setCursor(Qt.CursorShape.OpenHandCursor)def initUI(self):self.setGeometry(0, 0, 300, 200)  # Set window sizeself.setWindowTitle('派森斗罗')self.setWindowIcon(QIcon('logo.png'))self.center()  # Center the window on the screendef center(self):qr=self.frameGeometry()cp=QGuiApplication.primaryScreen().availableGeometry().center()qr.moveCenter(cp)self.move(qr.topLeft())if __name__ == '__main__':app = QApplication(sys.argv)ex = MyApplication()ex.show()sys.exit(app.exec())

窗口双击更换背景

import sys
import typing
from PyQt6.QtWidgets import QApplication, QMainWindow,QSystemTrayIcon,QMenu,QFrame,QHBoxLayout,QVBoxLayout,QLineEdit, QPushButton, QLabel,QListWidget, QMenuBar, QWidget, QStackedWidget,QLabel,QListWidgetItem
from PyQt6.QtGui import (QIcon,QAction,QScreen, QGuiApplication,QColor,QResizeEvent,QDragMoveEvent,QMoveEvent,
QPixmap, QMovie)
from PyQt6.QtCore import (Qt,pyqtSignal,QRect,QPropertyAnimation,
QParallelAnimationGroup, QSequentialAnimationGroup, QPauseAnimation, QEasingCurve,QSize)
from PyQt6.QtWidgets import (QApplication, QWidget, QLabel, QLineEdit, QPushButton,QCheckBox,
QVBoxLayout, QHBoxLayout, QGridLayout,
QGraphicsOpacityEffect)class LoginWindow(QWidget):loginSuccessSignal = pyqtSignal()  # 登录成功的信号def __init__(self):super().__init__()self.configSize=(880,550)self.configBg=['bg.gif','bg1.gif','bg2.gif','bg3.gif','bg4.gif','bg5.gif',]self.initBg()self.initUI()self.center()self.fadeIn()def changeBg(self):movie_path='./assets/imgs/bg/'+self.configBg[(self.configBg.index(self.background_label.movie().fileName().split('/')[-1])+1)%len(self.configBg)]print(movie_path)movie=QMovie(movie_path)self.background_label.setMovie(movie)movie.setScaledSize(QSize(*self.configSize))movie.start()def mouseDoubleClickEvent(self,event):self.changeBg()def initBg(self):# 设置窗口无框架,设置大小self.setWindowFlag(Qt.WindowType.FramelessWindowHint)self.setFixedSize(*self.configSize)# 设置背景self.background_label = QLabel(self)self.background_label.setGeometry(self.rect())movie = QMovie('./assets/imgs/bg/'+self.configBg[0])# movie = QMovie("bg.gif")movie.setScaledSize(QSize(*self.configSize))self.background_label.setMovie(movie)movie.start()def mousePressEvent(self, event):# 鼠标按压,判断是否是鼠标左键并且点击点在窗口内if event.button() == Qt.MouseButton.LeftButton and self.geometry().contains(self.mapToGlobal(event.pos())):self.dis = self.mapToGlobal(event.pos()) - self.pos()self.dragging = Trueself.setCursor(Qt.CursorShape.ClosedHandCursor)def mouseMoveEvent(self, event):# 鼠标移动的时候判断是否是拖拽状态,如果是的话就移动窗口if self.dragging:self.move(self.mapToGlobal(event.pos()) - self.dis)def mouseReleaseEvent(self, event):# 鼠标释放的时候接触拖拽状态并且改变鼠标样式if event.button() == Qt.MouseButton.LeftButton and self.dragging:self.dragging = Falseself.setCursor(Qt.CursorShape.OpenHandCursor)def initUI(self):# 创建布局和部件main_layout = QVBoxLayout(self)close_layout = QHBoxLayout()top_layout = QHBoxLayout()center_layout = QVBoxLayout()bottom_layout=QHBoxLayout()logo_label = QLabel(self)logo_pixmap = QPixmap("logo.png").scaled(70,70)logo_label.setPixmap(logo_pixmap)logo_label.setAlignment(Qt.AlignmentFlag.AlignTop | Qt.AlignmentFlag.AlignLeft)software_label = QLabel("派森斗罗", self)software_label.setAlignment(Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter)software_label.setStyleSheet("font-size: 20px; font-weight: bold; color: white;")close_button = QPushButton("×", self)close_button.setFixedSize(50,50)close_button.setStyleSheet("QPushButton {background-color: rgba(0, 0, 0, 0); color: #616F77;font-size:25px;}\QPushButton:hover {background-color: #E22A27; color: white;}")close_button.clicked.connect(self.close)username_label = QLabel("账号:", self)password_label = QLabel("密码:", self)username_label.setStyleSheet("color:white;font-weight:bold;font-size:15px;")password_label.setStyleSheet("color:white;font-weight:bold;font-size:15px;")username_input = QLineEdit(self)password_input = QLineEdit(self)username_input.setFixedSize(180,30)password_input.setFixedSize(180,30)username_input.setStyleSheet("QLineEdit{border:0;background-color:rgba(80,100,100,150);padding:5px;color:white;font-weight:bold;}\QLineEdit:hover{background-color:rgba(0, 0, 0, 100);}")password_input.setEchoMode(QLineEdit.EchoMode.Password)password_input.setStyleSheet("QLineEdit{border:0;background-color:rgba(80,100,100,150);padding:5px;color:white;font-weight:bold;}\QLineEdit:hover{background-color:rgba(0, 0, 0, 100);}")remember_me_checkbox = QCheckBox("记住密码", self)remember_me_checkbox.setStyleSheet("color:white;")login_button = QPushButton("登录", self)login_button.setFixedSize(100,25)login_button.setStyleSheet("QPushButton{border:0;color:white;background-color:rgba(0, 0, 255, 150);font-weight:bold;}\QPushButton:hover{background-color:rgba(0, 0, 255, 80);}")login_button.clicked.connect(self.login)# login_button.clicked.connect(lambda x:print('登录'))register_label = QLabel("还没有账号?  ", self)register_label.setStyleSheet("color:white;")register_button = QPushButton("去注册", self)font=register_button.font()font.setUnderline(True)register_button.setFont(font)register_button.setStyleSheet("border:0;color:white;")register_button.clicked.connect(lambda x:print('注册'))# 添加部件到布局close_layout.addStretch(1)close_layout.addWidget(close_button)top_layout.addWidget(logo_label)top_layout.addWidget(software_label)top_layout.addStretch(1)center_layout.addWidget(username_label)center_layout.addWidget(username_input)center_layout.addWidget(password_label)center_layout.addWidget(password_input)center_layout.addWidget(remember_me_checkbox)center_layout.addWidget(login_button, alignment=Qt.AlignmentFlag.AlignCenter)center_layout.setAlignment(Qt.AlignmentFlag.AlignHCenter|Qt.AlignmentFlag.AlignVCenter)bottom_layout.addStretch(10)bottom_layout.addWidget(register_label)bottom_layout.addWidget(register_button)bottom_layout.addStretch(1)main_layout.addLayout(close_layout)main_layout.addLayout(top_layout)main_layout.addStretch(1)main_layout.addLayout(center_layout)main_layout.addStretch(5)main_layout.addLayout(bottom_layout)main_layout.addStretch(3)self.setWindowOpacity(0.0)def fadeIn(self):self.animation = QPropertyAnimation(self, b"windowOpacity")self.animation.setStartValue(0.0)self.animation.setEndValue(1.0)self.animation.setDuration(1000)self.animation.start()def fadeOut(self):self.animation = QPropertyAnimation(self, b"windowOpacity")self.animation.setStartValue(1.0)self.animation.setEndValue(0.0)self.animation.setDuration(1000)self.animation.finished.connect(self.quit)self.animation.start()def quit(self):self.loginSuccessSignal.emit()  # 发送登录成功信号self.close()def center(self):qr=self.frameGeometry()cp=QGuiApplication.primaryScreen().availableGeometry().center()qr.moveCenter(cp)self.move(qr.topLeft())def login(self):self.fadeOut()# if self.username_input.text() == '1' and self.password_input.text() == '1':#     self.fadeOut()

多软件图标排布

from PyQt6 import QtGui
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QScrollArea, QLabel, QGridLayout, QPushButton
from PyQt6.QtGui import QPixmap
import sys
import typing
from PyQt6.QtWidgets import QApplication, QMainWindow,QSystemTrayIcon,QMenu,QFrame,QHBoxLayout,QVBoxLayout,QLineEdit, QPushButton, QLabel,QListWidget, QMenuBar, QWidget, QStackedWidget,QLabel,QListWidgetItem
from PyQt6.QtGui import (QIcon,QAction,QScreen, QGuiApplication,QColor,QResizeEvent,QDragMoveEvent,QMoveEvent,QPixmap, QMovie)
from PyQt6.QtCore import (Qt,pyqtSignal,QRect,QPropertyAnimation,QParallelAnimationGroup, QSequentialAnimationGroup, QPauseAnimation, QEasingCurve,QSize)
from PyQt6.QtWidgets import (QApplication, QWidget, QLabel, QLineEdit, QPushButton,QCheckBox,QVBoxLayout, QHBoxLayout, QGridLayout,QGraphicsOpacityEffect)
class SoftwareWindow(QWidget):def __init__(self):super().__init__()self.initUI()self.initSoftList()def initUI(self):self.setWindowTitle('多软件窗口')self.setGeometry(100, 100, 700, 100)self.show()def initSoftList(self):# 模拟软件数据self.software_data = [{"name": "软件1", "icon_path": "assets/imgs/icons/sun.png"},{"name": "软件1", "icon_path": "assets/imgs/icons/sun.png"},{"name": "软件1", "icon_path": "assets/imgs/icons/sun.png"},{"name": "软件1", "icon_path": "assets/imgs/icons/sun.png"},{"name": "软件1", "icon_path": "assets/imgs/icons/sun.png"},{"name": "软件1", "icon_path": "assets/imgs/icons/sun.png"},{"name": "软件1", "icon_path": "assets/imgs/icons/sun.png"},{"name": "软件1", "icon_path": "assets/imgs/icons/sun.png"},{"name": "软件1", "icon_path": "assets/imgs/icons/sun.png"},{"name": "软件1", "icon_path": "assets/imgs/icons/sun.png"},{"name": "软件1", "icon_path": "assets/imgs/icons/sun.png"},{"name": "软件1", "icon_path": "assets/imgs/icons/sun.png"},]self.setSoftBoxs(con=self)def setSoftBoxs(self,con,box_width=120,box_height=160):# 创建包含软件图标和名称的布局layout = QGridLayout()print(con.width())row, col = 0, 0  # 行和列的起始位置# 能够容纳的行row_allow=self.width()//120for software in self.software_data:icon_path = software["icon_path"]name = software["name"]des='这是软件一ahhah哈哈哈哈哈'box=self.getSoftBox(name,icon_path,des,box_width=box_width,box_height=box_height)layout.addWidget(box, row, col)col += 1if col == row_allow:col = 0row += 1con.setLayout(layout)def getSoftBox(self,name,logo_path,des,box_width,box_height):box=QWidget()box.setFixedSize(box_width,box_height)box.setToolTip(des)# box.setStyleSheet("QWidget{background-color:pink}")box.setStyleSheet("QWidget{border:1px solid black;background-color:#FDF6E3;}")layout=QVBoxLayout()logo_label=QLabel()logo_label.setPixmap(QPixmap(logo_path).scaledToWidth(50))logo_label.setFixedSize(50,50)name_label=QLabel(name)des_label=QLabel(des)btn=QPushButton('打开')layout.addWidget(logo_label)layout.addWidget(name_label)layout.addWidget(des_label)layout.addWidget(btn)layout.setAlignment(logo_label,Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignVCenter)box.setLayout(layout)return boxif __name__ == '__main__':app = QApplication([])ex = SoftwareWindow()app.exec()

点击按钮打开新页面

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog, QVBoxLayout, QLabelclass MainWindow(QMainWindow):def __init__(self):super().__init__()# 创建主窗口self.setWindowTitle("派森斗罗")self.setGeometry(100, 100, 400, 200)# 创建按钮并连接点击信号与槽self.button = QPushButton("打开新窗口", self)self.button.clicked.connect(self.open_dialog)def open_dialog(self):# 创建对话框self.dialog = MyDialog()self.dialog.show()self.dialog.exec()class MyDialog(QDialog):def __init__(self):super().__init__()# 创建对话框中的控件layout = QVBoxLayout(self)label = QLabel("这是新窗口!", self)layout.addWidget(label)self.setWindowTitle("派森斗罗")self.setGeometry(200, 200, 300, 150)if __name__ == "__main__":app = QApplication(sys.argv)window = MainWindow()window.show()sys.exit(app.exec())

窗口中画一个框

import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt6.QtGui import QPainter, QBrush, QPen
from PyQt6.QtCore import Qt, QRect, QPointclass DrawingApp(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setGeometry(100, 100, 800, 600)self.setWindowTitle('Draw Rectangle')self.canvas = DrawingCanvas(self)self.setCentralWidget(self.canvas)self.show()class DrawingCanvas(QWidget):def __init__(self, parent):super().__init__(parent)self.setGeometry(0, 0, parent.width(), parent.height())self.origin = QPoint(0, 0)  # 初始化为 (0, 0)self.end = QPoint(0, 0)     # 初始化为 (0, 0)def paintEvent(self, event):painter = QPainter(self)# 设置绘制选项,启用抗锯齿。painter.setRenderHint(QPainter.RenderHint.Antialiasing)rect = QRect(self.origin, self.end)painter.drawRect(rect)def mousePressEvent(self, event):if event.button() == Qt.MouseButton.LeftButton:self.origin = event.pos()self.end = event.pos()def mouseMoveEvent(self, event):if event.buttons() & Qt.MouseButton.LeftButton:self.end = event.pos()self.update()def mouseReleaseEvent(self, event):if event.button() == Qt.MouseButton.LeftButton:self.end = event.pos()self.update()if __name__ == '__main__':app = QApplication(sys.argv)ex = DrawingApp()sys.exit(app.exec())

介绍一下QGraphicsScene和QGraphicsView

QGraphicsSceneQGraphicsView 是 PyQt 中用于创建图形用户界面的两个关键类,它们一起协同工作,提供了一种灵活的图形表示方法。以下是它们的主要介绍:

QGraphicsScene

QGraphicsScene 是一个二维图形场景,它允许你在其中添加、移动和交互多个 2D 图形项(QGraphicsItem)。图形项可以是简单的图形元素,如矩形、椭圆和文本,也可以是自定义的图形元素。QGraphicsScene 提供了以下主要功能:

  1. 管理图形项: QGraphicsScene 维护了一个图形项的列表,你可以在其中添加、移除和操纵图形项。
  2. 场景坐标系: 每个图形项都有自己的局部坐标系,而 QGraphicsScene 提供了一个全局坐标系,使你能够在场景中的不同图形项之间执行坐标转换。
  3. 事件处理: QGraphicsScene 可以接收鼠标、键盘和其他事件,你可以通过重写相应的事件处理方法来响应这些事件。
  4. 图形项选择: 你可以选择一个或多个图形项,执行相应的操作,比如拖动、删除等。

QGraphicsView

QGraphicsView 是用于在窗口中显示 QGraphicsScene 的视图类。它提供了以下主要功能:

  1. 显示场景: QGraphicsView 提供一个用于显示 QGraphicsScene 内容的视图窗口。你可以在一个窗口中显示多个 QGraphicsView,每个视图显示同一个或不同的场景。
  2. 视图变换: 通过视图变换,你可以对场景进行平移、缩放、旋转等操作。这使得你可以轻松地实现图形的缩放和平移效果。
  3. 视图更新: 当场景中的图形项发生变化时,QGraphicsView 负责更新视图,以便反映这些变化。
  4. 事件转发: QGraphicsView 接收鼠标、键盘等事件,并将它们传递给场景中的图形项进行处理。
  5. 交互支持: QGraphicsView 提供了一些方便的方法来支持用户的交互,比如启用鼠标拖拽、缩放等。

通过将 QGraphicsSceneQGraphicsView 结合使用,你可以创建出富有交互性的图形界面,用于显示和操作图形元素。这对于图形编辑器、CAD 应用、数据可视化等领域非常有用。

图片浏览,可以放大缩小拖拽

import sys
from PyQt6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsPixmapItem, QMainWindow
from PyQt6.QtCore import Qt, QPointF
from PyQt6.QtGui import QPixmap, QWheelEvent, QPainterclass ImageViewer(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setGeometry(100, 100, 800, 600)self.setWindowTitle('Image Viewer')self.scene = QGraphicsScene(self)self.view = GraphicsView(self.scene, self)self.setCentralWidget(self.view)# Load an example imageimage_path = 'letter.png'  # Replace with the actual path to your imagepixmap = QPixmap(image_path)item = QGraphicsPixmapItem(pixmap)self.scene.addItem(item)self.show()class GraphicsView(QGraphicsView):def __init__(self, scene, parent):super().__init__(scene, parent)self.setRenderHint(QPainter.RenderHint.Antialiasing, True)self.setStyleSheet('GraphicsView{background-color:#FDF6E3;}')self.setDragMode(QGraphicsView.DragMode.ScrollHandDrag)  # Enable hand-drag modedef wheelEvent(self, event: QWheelEvent):modifiers = event.modifiers()if modifiers == Qt.KeyboardModifier.ControlModifier:# Zoom only if Ctrl key is pressedfactor = 1.2  # Zoom factorif event.angleDelta().y() < 0:factor = 1.0 / factor  # Zoom out for a negative wheel eventself.scale(factor, factor)def main():app = QApplication(sys.argv)viewer = ImageViewer()sys.exit(app.exec())if __name__ == '__main__':main()

图片浏览,ctrl+滚轮放大缩小,左键按压拖拽,右键按压画框,框显示坐标信息

import sys
from PyQt6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsPixmapItem, QGraphicsRectItem, QMainWindow, QGraphicsTextItem
from PyQt6.QtCore import Qt, QRectF
from PyQt6.QtGui import QPixmap, QPainter, QFontclass ImageViewer(QMainWindow):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setGeometry(100, 100, 800, 600)self.setWindowTitle('Image Viewer')self.scene = QGraphicsScene(self)self.view = GraphicsView(self.scene, self)self.setCentralWidget(self.view)# Load an example imageimage_path = 'letter.png'  # Replace with the actual path to your imagepixmap = QPixmap(image_path)item = QGraphicsPixmapItem(pixmap)self.scene.addItem(item)self.show()class GraphicsView(QGraphicsView):def __init__(self, scene, parent):super().__init__(scene, parent)self.setStyleSheet('GraphicsView{background-color:#FDF6E3;}')self.setRenderHint(QPainter.RenderHint.Antialiasing, True)self.setDragMode(QGraphicsView.DragMode.ScrollHandDrag)  # 启用拖拽模式self.drawing_rect = Noneself.origin = Noneself.is_drawing = Falseself.coordinate_text_items = {}  # 存储坐标信息的字典,以矩形为键def wheelEvent(self, event):modifiers = event.modifiers()if modifiers == Qt.KeyboardModifier.ControlModifier:# 只有在按下 Ctrl 键时才缩放factor = 1.2  # 缩放因子if event.angleDelta().y() < 0:factor = 1.0 / factor  # 对于负的滚轮事件进行缩小self.scale(factor, factor)def mouseDoubleClickEvent(self, event):super().mouseDoubleClickEvent(event)if event.button() == Qt.MouseButton.LeftButton:# 获取鼠标双击的位置double_click_position = event.pos()# 获取双击位置相对于原图的像素位置double_click_scene_position = self.mapToScene(double_click_position)# 获取点击位置相对于原图的像素位置item = self.scene().itemAt(double_click_scene_position, self.transform())if isinstance(item, QGraphicsRectItem):# 删除被点击的矩形的坐标信息rect_key = id(item)if rect_key in self.coordinate_text_items:self.removeCoordinateTextItems(self.coordinate_text_items[rect_key])# 删除被点击的矩形self.scene().removeItem(item)def mouseMoveEvent(self, event):super().mouseMoveEvent(event)if event.buttons() & Qt.MouseButton.RightButton:if self.is_drawing and self.origin is not None:# 获取鼠标当前位置current_position = event.pos()# 获取当前位置相对于原图的像素位置current_scene_position = self.mapToScene(current_position)# 更新矩形的大小self.drawing_rect.setRect(QRectF(self.origin, current_scene_position))# 实时显示图像scene_rect = self.sceneRect()self.setSceneRect(scene_rect)def mouseReleaseEvent(self, event):super().mouseReleaseEvent(event)if event.button() == Qt.MouseButton.RightButton:if self.is_drawing and self.origin is not None:self.is_drawing = False# 获取鼠标释放的位置release_position = event.pos()# 获取释放位置相对于原图的像素位置release_scene_position = self.mapToScene(release_position)# 更新矩形的大小self.drawing_rect.setRect(QRectF(self.origin, release_scene_position))# 显示矩形的坐标信息self.showRectCoordinates(self.drawing_rect)def mousePressEvent(self, event):super().mousePressEvent(event)if event.button() == Qt.MouseButton.RightButton:if not self.is_drawing:# 获取鼠标点击的位置click_position = event.pos()# 获取点击位置相对于原图的像素位置scene_position = self.mapToScene(click_position)self.origin = scene_positionself.is_drawing = True# 创建一个新的矩形self.drawing_rect = QGraphicsRectItem(QRectF(self.origin, self.origin))self.scene().addItem(self.drawing_rect)def showRectCoordinates(self, rect_item):# 获取矩形的左上角和右下角相对于图片的坐标rect_top_left = rect_item.rect().topLeft()rect_bottom_right = rect_item.rect().bottomRight()# 将坐标转换为整数rect_top_left = rect_top_left.toPoint()rect_bottom_right = rect_bottom_right.toPoint()# 在矩形的左上角显示坐标信息text_item_top_left = QGraphicsTextItem(f"({rect_top_left.x()}, {rect_top_left.y()})")text_item_top_left.setPos(rect_top_left.x(), rect_top_left.y() - 15)self.scene().addItem(text_item_top_left)# 在矩形的右下角显示坐标信息text_item_bottom_right = QGraphicsTextItem(f"({rect_bottom_right.x()}, {rect_bottom_right.y()})")text_item_bottom_right.setPos(rect_bottom_right.x() - 60, rect_bottom_right.y() + 5)self.scene().addItem(text_item_bottom_right)# 存储矩形和坐标信息的关联rect_key = id(rect_item)self.coordinate_text_items[rect_key] = [text_item_top_left, text_item_bottom_right]def removeCoordinateTextItems(self, items):# 删除与矩形关联的坐标信息for item in items:self.scene().removeItem(item)def main():app = QApplication(sys.argv)viewer = ImageViewer()sys.exit(app.exec())if __name__ == '__main__':main()
给出这样一个pyqt6程序,左边是刚才的窗口,窗口右边有按钮和输入框,分别可以输入:
背景图像选择框,字体选择框,字体大小,字体颜色设置,文字区域左顶点,
右顶点,字间隔,行间距,行间距随机扰动值,字体大小随机扰动值,字间距随机扰动值font=ImageFont.truetype("hand.ttf", size=100),line_spacing=150,fill=0,  # 字体“颜色”left_margin=100,top_margin=100,right_margin=100,bottom_margin=100,word_spacing=15,# line_spacing_sigma=6,  # 行间距随机扰动line_spacing_sigma=0,  # 行间距随机扰动# font_size_sigma=20,  # 字体大小随机扰动# font_size_sigma=2,  # 字体大小随机扰动font_size_sigma=0,  # 字体大小随机扰动word_spacing_sigma=0,  # 字间距随机扰动# word_spacing_sigma=3,  # 字间距随机扰动start_chars="“([<",  # 特定字符提前换行,防止出现在行尾end_chars=",。",  # 防止特定字符因排版算法的自动换行而出现在行首perturb_x_sigma=0,  # 笔画横向偏移随机扰动# perturb_x_sigma=4,  # 笔画横向偏移随机扰动perturb_y_sigma=0,  # 笔画纵向偏移随机扰动# perturb_y_sigma=4,  # 笔画纵向偏移随机扰动perturb_theta_sigma=0,  # 笔画旋转偏移随机扰动
查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"PyQt6实战开发之旅-代码均可运行":http://eshow365.cn/6-42197-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!