学习感悟
由于官方文档是英文的,所以学习起来不是很直观。
网上的中文教程也都有点偏重就轻,去从头学习细枝末节不是很必要。假如每个控件组件讲十分钟,几百个控件可想而知。
最关键的是有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_STR
print(QT_VERSION_STR)
print(PYQT_VERSION_STR)
程序实战
第一个程序
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel
from PyQt6.QtGui import QIcon
def 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 QIcon
class MyApplication(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(0, 0, 300, 200) # Set window size
self.setWindowTitle('派森斗罗')
self.setWindowIcon(QIcon('logo.png'))
self.center() # Center the window on the screen
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)
ex = MyApplication()
ex.show()
sys.exit(app.exec())
PyQt6-初探QMainWindow-各模块的学习方法
QMainWindow是Qt框架中的一个类,用于创建主窗口应用程序。它提供了一个具有一般应用程序框架的主窗口,包括菜单栏、工具栏、状态栏和中央工作区域。
以下是QMainWindow的一些主要特性:
- 菜单栏(Menu Bar):QMainWindow允许你添加菜单栏,通过菜单栏你可以创建各种菜单,包括文件、编辑、视图等。
- 工具栏(Tool Bar): 你可以在主窗口上添加工具栏,工具栏通常包含一些常用的工具按钮,例如打开、保存、剪切、复制等。
- 状态栏(Status Bar):QMainWindow还提供了一个状态栏,用于显示应用程序的状态信息或者当前操作的相关信息。
- 中央工作区域(Central Widget): 主要的应用程序界面通常放置在中央工作区域,这是一个可以包含其他Qt小部件的区域,例如文本编辑器、图形视图等。
- Dock小部件(Dock Widgets):QMainWindow支持将一些小部件作为停靠窗口,可以通过拖拽将它们放置在主窗口的边缘。
- 窗口管理功能: 包括最大化、最小化、关闭等窗口管理功能。
下面是一个简单的例子,演示如何创建一个基本的QMainWindow:
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel
class 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中,可以使用QTabWidget
和QWidget
来实现多页面切换。
当然你也可以自定义组件来实现这样的功能。在这里我们使用QTabWidget
和QWidget
以下是一个简单的示例:
import sys
from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QTabWidget, QVBoxLayout, QPushButton, QWidget
from PyQt6.QtGui import QIcon
class 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
作为其中心部件。然后,我们创建了两个QWidget
(page1
和page2
),并将它们添加到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 QIcon
class 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 Qt
class 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,QIcon
class 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 Qt
class 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 中实现多页面切换通常有多种方法,其中两种主要方法是使用 QStackedWidget
和 QTabWidget
。以下是如何使用这两种方法实现多页面切换的总结:
- 使用 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) # 切换到第一个页面
- 使用 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 中,QTabWidget
和 QStackedWidget
是用于处理多页面(或多视图)的两个不同的部件。它们有一些区别,主要在于它们的设计和用途。
QTabWidget:
- 标签页式布局:
QTabWidget
提供了一个标签页式的用户界面,允许用户通过选项卡(标签页)来切换不同的页面。 - 导航和可见性: 用户可以通过点击选项卡切换页面。每个选项卡上通常有一个相关的标题,并且用户可以通过点击标题来选择相应的页面。
- 集成标签栏:
QTabWidget
自动提供了一个标签栏,用于容纳选项卡。标签栏通常位于部件的顶部。 - 适用于多个页面场景: 当您有一组相关的页面,希望以标签页的形式进行切换时,
QTabWidget
是一个很好的选择。
from PyQt6.QtWidgets import QApplication, QWidget, QTabWidget, QVBoxLayout, QLabel
app = 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:
- 堆栈式布局:
QStackedWidget
提供了一个堆栈式的用户界面,允许用户通过推入和弹出页面来切换。 - 程序控制切换: 切换页面通常是由程序控制的,而不是用户通过点击标签页来触发的。
- 没有集成标签栏:
QStackedWidget
不提供内置的标签栏。相反,您需要使用其他部件(例如按钮、菜单)来触发页面切换。 - 适用于单个页面显示: 当您有多个页面,但同一时间只显示其中一个页面时,
QStackedWidget
是一个很好的选择。
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QPushButton, QStackedWidget
app = 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 中,QFrame
和 QWidget
是两个不同的类,它们用于创建界面上的可视化组件,但有一些区别。
**QFrame**
** 类:**QFrame
是QWidget
的子类,因此QFrame
可以包含在其他QWidget
内或作为QMainWindow
的中心部件。QFrame
是一个简单的容器,通常用于包含其他小部件或进行布局管理。QFrame
通常用于创建矩形框架,比如创建边框、背景或者一些特殊的辅助图形元素。
from PyQt6.QtWidgets import QFrame
frame = QFrame()
**QWidget**
** 类:**QWidget
是一个通用的用户界面对象,也是QFrame
的基类。QWidget
通常用于创建应用程序的主窗口或作为主窗口中的中心部件。- 与
QFrame
相比,QWidget
是更通用的界面元素,可以包含其他小部件,并提供更多的功能。
from PyQt6.QtWidgets import QWidget
widget = QWidget()
总的来说,QFrame
更专注于创建框架和辅助图形,而 QWidget
是一个更通用的界面元素,可以包含其他小部件并提供更广泛的功能。在实际使用中,你可以根据需求选择使用 QWidget
或 QFrame
。
先显示登陆页面,登陆成功后显示主页面
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QLineEdit, QPushButton, QLabel
from PyQt6 import QtCore
from PyQt6.QtGui import QIcon
class 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 QPropertyAnimation
class 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 0
self.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 QGuiApplication
class 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.OutQuad
self.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 QGuiApplication
class 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 QGuiApplication
class 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 qr
if __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, QAction
class 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,QLabel
class 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=0
self.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+=2
self.tmp_y+=1
self.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 = True
self.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 = False
self.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=0
self.tmp_y=0
self.dx=2
self.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.dy
self.tmp_x+=self.dx
self.tmp_y+=self.dy
self.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 = True
self.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 = False
self.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 = True
self.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 = False
self.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 = True
self.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 = False
self.setCursor(Qt.CursorShape.OpenHandCursor)
def initUI(self):
self.setGeometry(0, 0, 300, 200) # Set window size
self.setWindowTitle('派森斗罗')
self.setWindowIcon(QIcon('logo.png'))
self.center() # Center the window on the screen
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)
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 = True
self.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 = False
self.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()//120
for 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 += 1
if col == row_allow:
col = 0
row += 1
con.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 box
if __name__ == '__main__':
app = QApplication([])
ex = SoftwareWindow()
app.exec()
点击按钮打开新页面
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog, QVBoxLayout, QLabel
class 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, QPoint
class 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
QGraphicsScene
和 QGraphicsView
是 PyQt 中用于创建图形用户界面的两个关键类,它们一起协同工作,提供了一种灵活的图形表示方法。以下是它们的主要介绍:
QGraphicsScene
QGraphicsScene
是一个二维图形场景,它允许你在其中添加、移动和交互多个 2D 图形项(QGraphicsItem
)。图形项可以是简单的图形元素,如矩形、椭圆和文本,也可以是自定义的图形元素。QGraphicsScene
提供了以下主要功能:
- 管理图形项:
QGraphicsScene
维护了一个图形项的列表,你可以在其中添加、移除和操纵图形项。 - 场景坐标系: 每个图形项都有自己的局部坐标系,而
QGraphicsScene
提供了一个全局坐标系,使你能够在场景中的不同图形项之间执行坐标转换。 - 事件处理:
QGraphicsScene
可以接收鼠标、键盘和其他事件,你可以通过重写相应的事件处理方法来响应这些事件。 - 图形项选择: 你可以选择一个或多个图形项,执行相应的操作,比如拖动、删除等。
QGraphicsView
QGraphicsView
是用于在窗口中显示 QGraphicsScene
的视图类。它提供了以下主要功能:
- 显示场景:
QGraphicsView
提供一个用于显示QGraphicsScene
内容的视图窗口。你可以在一个窗口中显示多个QGraphicsView
,每个视图显示同一个或不同的场景。 - 视图变换: 通过视图变换,你可以对场景进行平移、缩放、旋转等操作。这使得你可以轻松地实现图形的缩放和平移效果。
- 视图更新: 当场景中的图形项发生变化时,
QGraphicsView
负责更新视图,以便反映这些变化。 - 事件转发:
QGraphicsView
接收鼠标、键盘等事件,并将它们传递给场景中的图形项进行处理。 - 交互支持:
QGraphicsView
提供了一些方便的方法来支持用户的交互,比如启用鼠标拖拽、缩放等。
通过将 QGraphicsScene
和 QGraphicsView
结合使用,你可以创建出富有交互性的图形界面,用于显示和操作图形元素。这对于图形编辑器、CAD 应用、数据可视化等领域非常有用。
图片浏览,可以放大缩小拖拽
import sys
from PyQt6.QtWidgets import QApplication, QGraphicsView, QGraphicsScene, QGraphicsPixmapItem, QMainWindow
from PyQt6.QtCore import Qt, QPointF
from PyQt6.QtGui import QPixmap, QWheelEvent, QPainter
class 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 image
image_path = 'letter.png' # Replace with the actual path to your image
pixmap = 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 mode
def wheelEvent(self, event: QWheelEvent):
modifiers = event.modifiers()
if modifiers == Qt.KeyboardModifier.ControlModifier:
# Zoom only if Ctrl key is pressed
factor = 1.2 # Zoom factor
if event.angleDelta().y() < 0:
factor = 1.0 / factor # Zoom out for a negative wheel event
self.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, QFont
class 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 image
image_path = 'letter.png' # Replace with the actual path to your image
pixmap = 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 = None
self.origin = None
self.is_drawing = False
self.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_position
self.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, # 笔画旋转偏移随机扰动