现在来说一下常用的一个写界面的方式,算是自身的积累,也希望能给需要的朋友一些启发
一、关于界面
可以用qtdesigner来画,也可以用代码来生成
[Python] 纯文本查看 复制代码from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QStackedWidget, \
QLabel, QSystemTrayIcon, QMenu
from PySide6.QtCore import Qt, QFile, QTextStream, QIODevice
from PySide6.QtGui import QIcon, QAction
import res_rc
import sys
import os
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initialize_tray()
self.iniUI()
# 加载qss
style_qss = ":style/style.qss"
stream = QFile(style_qss)
stream.open(QIODevice.ReadOnly)
content = QTextStream(stream).readAll()
self.setStyleSheet(content)
# 加载ico
icon = ":ico/demo.png"
self.setWindowIcon(QIcon(icon))
self.center()
def iniUI(self):
self.setWindowTitle("Demo")
self.setGeometry(200, 200, 800, 600)
# self.setWindowIcon(QIcon("memo.ico")) # 可替换为你的图标路径
# 主窗口布局
main_layout = QHBoxLayout()
# 左侧导航栏
self.button_names_list = ["界面1", "界面2", "界面3", "设置", "关于"]
nav_widget, self.buttons = self.create_navigation()
# 1.左侧导航栏
main_layout.addWidget(nav_widget)
# 2.右侧内容区,根据按钮数来创建新的界面
self.stack = QStackedWidget()
for i in range(1, len(self.button_names_list) + 1):
if i == 1:
# 第一个界面是已经确定的,直接调用
self.page_work_memo = self.create_page(f"This is Page {i}", "#88C0D0")
self.stack.addWidget(self.page_work_memo)
else:
self.page = self.create_page(f"This is Page {i}", "#88C0D0")
self.stack.addWidget(self.page)
main_layout.addWidget(self.stack)
# 创建中央小部件
central_widget = QWidget()
central_widget.setLayout(main_layout)
self.setCentralWidget(central_widget)
# 连接按钮事件
for i, button in enumerate(self.buttons):
button.clicked.connect(lambda checked, idx=i: self.switch_page(idx))
# 创建左侧导航栏
def create_navigation(self):
"""创建导航栏"""
nav_widget = QWidget()
nav_layout = QVBoxLayout()
nav_widget.setLayout(nav_layout)
nav_widget.setFixedWidth(100)
buttons = []
for i, text in enumerate(self.button_names_list):
button = QPushButton(text)
button.setObjectName(f"btn_{i}")
buttons.append(button)
nav_layout.addWidget(button)
# 在添加最后一个前,addstretch
if i == len(self.button_names_list) - 3:
nav_layout.addStretch()
return nav_widget, buttons
def switch_page(self, index):
"""切换页面并更新按钮样式"""
self.stack.setCurrentIndex(index)
def create_page(self, text, color):
"""创建页面内容"""
page = QWidget()
layout = QVBoxLayout()
label = QLabel(text)
label.setAlignment(Qt.AlignCenter)
layout.addWidget(label)
page.setLayout(layout)
return page
def initialize_tray(self):
"""初始化系统托盘图标"""
self.tray_icon = QSystemTrayIcon(self)
icon = ":ico/demo.png"
if icon:
self.tray_icon.setIcon(QIcon(icon))
else:
print("托盘图标未找到")
self.tray_icon.setToolTip('Demo')
self.tray_icon.setVisible(True)
self.setup_tray_menu()
def get_absolute_path(self, relative_path):
"""根据相对路径获取绝对路径"""
if getattr(sys, 'frozen', False):
# 如果程序是打包后的,则使用 sys._MEIPASS 获取临时目录路径
base_dir = sys._MEIPASS
else:
# 如果是开发环境下运行,使用当前文件路径
base_dir = os.path.dirname(__file__)
absolute_path = os.path.join(base_dir, relative_path) # 拼接出绝对路径
return absolute_path if os.path.exists(absolute_path) else None
def setup_tray_menu(self):
"""设置托盘菜单"""
tray_menu = QMenu()
show_action = QAction('显示界面', self)
show_action.triggered.connect(self.show_window)
tray_menu.addAction(show_action)
quit_action = QAction('退出', self)
quit_action.triggered.connect(self.quit)
tray_menu.addAction(quit_action)
self.tray_icon.setContextMenu(tray_menu)
self.tray_icon.activated.connect(self.tray_icon_activated)
def tray_icon_activated(self, reason):
if reason == QSystemTrayIcon.Trigger:
self.show_window()
def quit(self):
"""保存数据并退出"""
self.close()
QApplication.quit()
def show_window(self):
"""显示主窗口"""
self.showNormal()
self.activateWindow()
def closeEvent(self, event):
event.ignore() # 忽略关闭事件
self.hide() # 隐藏主窗口
def center(self):
# 获取屏幕大小
screen_geometry = QApplication.screens()[0].availableGeometry()
screen_width = screen_geometry.width()
screen_height = screen_geometry.height()
# 计算窗口位置
x = (screen_width - self.width()) // 2
y = (screen_height - self.height()) // 2
# 设置窗口位置
self.move(x, y)
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec()
如上,是使用代码生成的一个简单界面,包含了左侧有一个导航栏,能够通过点击不同的按钮来切换不同的界面,并带有系统托盘
1.jpg (48.18 KB, 下载次数: 0)
下载附件
2025-1-13 22:51 上传
二、关于界面美化
如果光写出来的界面,美化效果肯定是不够的(看我贴子的朋友可以发现,最近的小工具界面似乎更美观了)
所以可以用以下方法
1.可以将软件界面各元素的美化(StyleSheet属性)写在ui界面中(或直接在qtdesigner中写)
例如:
[Python] 纯文本查看 复制代码button.setStyleSheet("""
QPushButton {
background-color: #4C566A;
color: white;
font-size: 18px;
border: none;
padding: 10px;
text-align: left;
}
QPushButton:hover {
background-color: #5E81AC;
}
""")
2.为了更好地将界面与美化效果分离,可以使用新建qss文件的方法,定制ui中出现的元素的stylesheet
如下:
[Python] 纯文本查看 复制代码/* 主窗口背景颜色 */
QWidget {
background-color: #2E3440;
color: #ECEFF4;
font-family: "Microsoft YaHei", sans-serif;
font-size: 16px;
}
/* 按钮样式 */
QPushButton {
background-color: #4C566A;
color: #ECEFF4;
font-size: 18px;
border: 2px solid #4C566A;
border-radius: 10px;
padding: 8px 16px;
text-align: center;
transition: all 0.3s ease;
}
QPushButton:hover {
background-color: #5E81AC;
border-color: #81A1C1;
color: #ECEFF4;
}
QPushButton:pressed {
background-color: #3B4252;
border-color: #88C0D0;
color: #ECEFF4;
}
/* 标签样式 */
QLabel {
font-size: 20px;
font-weight: bold;
color: #ECEFF4;
background-color: #4C566A;
border-radius: 8px;
padding: 10px;
text-align: center;
}
/* 左侧导航栏按钮样式 */
#btn_0, #btn_1, #btn_2 {
background-color: #3B4252;
color: #ECEFF4;
border-radius: 10px;
font-size: 16px;
padding: 10px 8px;
}
#btn_0:hover, #btn_1:hover, #btn_2:hover {
background-color: #5E81AC;
}
#btn_0:checked, #btn_1:checked, #btn_2:checked {
background-color: #88C0D0;
color: #2E3440;
}
/* 滚动条样式 */
QScrollBar:vertical {
background: #2E3440;
width: 10px;
margin: 0px;
border-radius: 5px;
}
QScrollBar::handle:vertical {
background: #5E81AC;
min-height: 20px;
border-radius: 5px;
}
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical {
background: none;
}
QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
background: none;
}
/* 系统托盘菜单样式 */
QMenu {
background-color: #3B4252;
border: 1px solid #4C566A;
color: #ECEFF4;
}
QMenu::item {
padding: 8px 20px;
background-color: transparent;
}
QMenu::item:selected {
background-color: #5E81AC;
}
/* 提示文本样式 */
QToolTip {
background-color: #4C566A;
color: #ECEFF4;
border: 1px solid #88C0D0;
border-radius: 5px;
padding: 4px;
}
然后呢,新建一个qrc文件,同样有两种方法
1.在qtdesigner中新建
2.jpg (290.65 KB, 下载次数: 0)
下载附件
2025-1-13 23:00 上传
2.直接新建一个qrc文件,其代码如下(我这里是添加了icon文件及qss文件):
[Python] 纯文本查看 复制代码
style.qss
demo.png
TIPS:如有其他的可以继续添加
三、在界面中调用QSS文件
1.首先是相关配置,Setting-Tools-External Tools,添加qrc转换成py的功能
(此项可百度,我这里是添加了新建UI,打开UI,UI2PY,QRC2PY)
3.jpg (48.22 KB, 下载次数: 0)
下载附件
2025-1-13 23:04 上传
三句代码分别如下(第一句是找到rcc文件路径,pyqt5或pyqt6可能稍有不同,另用户名需要修改成你的):
[Python] 纯文本查看 复制代码C:\Users\用户名\AppData\Local\Programs\Python\Python310\Scripts\pyside6-rcc.exe
$FileName$ -o $FileNameWithoutExtension$_rc.py
$FileDir$
2.在代码中调用qss文件
(1)首先是执行转换,如图设置后,会生成一个**_rc.py文件
4.jpg (134.54 KB, 下载次数: 0)
下载附件
2025-1-13 23:14 上传
导入转换后的py文件
[Python] 纯文本查看 复制代码import res_rc
然后在代码中引用它
[Python] 纯文本查看 复制代码# 加载qss
style_qss = ":style/style.qss"
stream = QFile(style_qss)
stream.open(QIODevice.ReadOnly)
content = QTextStream(stream).readAll()
self.setStyleSheet(content)
# 加载ico
icon = ":ico/demo.png"
self.setWindowIcon(QIcon(icon))
这样做的好处是:
1.由于qss或ico文件均已经由qrc资源文件转换成二进制文件,所以不需要再单独引入它们(如在spec中重新定义路径)
2.在美化界面时,只需要修改qss文件,然后再次执行一次qrc文件转py文件,即可生效,比较方便,不需要修改主代码的逻辑
四、Demo示例代码
通过网盘分享的文件:Demo
链接: https://pan.baidu.com/s/1bho_QD460LlNLnqshn_nRg?pwd=r86h 提取码: r86h