pyQt基础4(对话框)
一、对话框实现
"""
除了消息对话框有两种调用方式,其他对话框只能静态调用
"""
import sysfrom PyQt6 import QtCore, QtGui, QtWidgets, uic
from PyQt6.QtCore import Qt, QFile, QIODevice, QIODeviceBase
from PyQt6.QtGui import QPixmap, QMovie, QIcon, QFont, QColor
from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QLineEdit, QComboBox, QFileDialog, \QMessageBox, QToolButton, QWidget, QFontDialog, QColorDialogclass MyWidget(QWidget):def __init__(self, ):super().__init__()ui = uic.loadUi('2ui_textEdit.ui', self)# 绑定self.textEdit: QLineEdit = ui.textEditself.fontBtn: QPushButton = ui.fontBtnself.colorBtn: QPushButton = ui.colorBtnself.openBtn: QPushButton = ui.openBtnself.saveBtn: QPushButton = ui.saveBtn# 设置信号与槽函数的连接self.fontBtn.clicked.connect(self.fontBtn_slot) # 字体对话框self.colorBtn.clicked.connect(self.colorBtn_slot) # 颜色对话框self.openBtn.clicked.connect(self.openBtn_slot) # 文件对话框self.saveBtn.clicked.connect(self.saveBtn_slot)# 1、字体按钮对应的槽函数# 字体对话框def fontBtn_slot(self):# QFontDialog返回两个值,一个是QFont(包含字体信息),一个是bool值(代表用户是否设置了字体)。font, font_choose = QFontDialog.getFont(QFont("黑体", 10, 10),self,"选择字体",)if font_choose:# self.textEdit.setFont(font) #将全部的文本设置成该字体self.textEdit.setCurrentFont(font) # 设置选中字的字体else:QMessageBox.information(self, "提示", "没有选择字体")# 2、颜色按钮对应的槽函数# 颜色对话框def colorBtn_slot(self):""" getColor(initial: Union[QColor, Qt.GlobalColor, int] = Qt.white, #初始颜色parent: Optional[QWidget] = None, #父对象title: Optional[str] = '', #标题options: QColorDialog.ColorDialogOption = QColorDialog.ColorDialogOptions()) # *设置*-> QColor """color = QColorDialog.getColor(QColor(0, 0, 0),self, "选择颜色",) # 函数返回值是QColor,没有bool值# 判断用户是否选中有效颜色color_choose = color.isValid()if color_choose:self.textEdit.setTextColor(color) # 设置字体颜色# self.textEdit.setTextBackgroundColor(color) #设置字体背景颜色else:QMessageBox.information(self, "提示", "没有选择颜色")def openBtn_slot(self):# 3、文件对话框file_path,file_type = QFileDialog.getOpenFileName(self, # 父组件"打开文件", # 标题"./", # 起始路径,"./"表示当前路径"Images(*.png *.jpg *.ico);;文本Text(*.txt);;XML(*.xml)",# 过滤器文本Text、Images等可以自己设置,类型内部用空格分隔,类型之间用两个分号分隔"文本Text",# 默认的起始过滤器# ["x","x"],# 第一个str表示文件路径,第二个str表示文件类型)if file_path :# QFile实例化一个对象,QIODeviceBase用于读取file = QFile(file_path)file.open(QIODeviceBase.OpenModeFlag.ReadWrite)msg = file.readAll() # 读取全部,返回的是QByteArray类型--------------------------------------------------------------------------------msg = msg.data().decode("utf-8") # 将QByteArray类型转为utf-8字符self.textEdit.setText(msg)file.close()def saveBtn_slot(self):""" getSaveFileName(parent: Optional[QWidget] = None,caption: Optional[str] = '',directory: Optional[str] = '',filter: Optional[str] = '',initialFilter: Optional[str] = '',options: QFileDialog.Option = QFileDialog.Options()) -> tuple[str, str] """file_path,file_type = QFileDialog.getSaveFileName(self,"保存文件","./","Images(*.png *.jpg *.ico);;文本Text(*.txt);;XML(*.xml)","文本Text")# 获取文本内容text = self.textEdit.toPlainText() # 注意这是textEdit,如果时lineedit不是这个if not file_path:# 用户点击取消,什么也不做,直接返回returnif not text:QMessageBox.information(self, "提示", "不存在文本")returnwith open(file_path, "w", encoding="utf-8") as file:file.write(text) # 如果文本量极大可改成一行一行写入。QMessageBox.warning(self, "错误", f"保存文件失败:{e}")if __name__ == '__main__':app = QApplication(sys.argv)myWidget = MyWidget()myWidget.show()sys.exit(app.exec()) # exec的返回值是关闭缩小化等操作,传给sys后即可正常关闭,用于阻塞调用,让应用程序不要运行完就关闭而是等待用户操作
对话框保存功能展示:
二、登录界面再次优化
增加功能:
1、页面跳转2、页面1不同聊天对象名字的切换(暂未完成聊天页面的切换)
3、页面2组的创建,建立了对应Item的双击信号,建立了一个跳转消息框的槽函数(暂未完成跳转至对应聊天页面的槽函数)
"""
引入信号和槽函数pyside6-uic.exe test.ui -o test.py #将ui界面文件转化成py文件
pyside6-rcc res.qrc -o res_rc.py # 将.qrc文件转化成py文件
"""
import sysfrom PySide6.QtCore import Qt
from PySide6.QtWidgets import QWidget, QApplication, QPushButton, QMainWindow, QToolBar, QDockWidget, QMessageBox, \QTextEdit, QStackedWidget, QVBoxLayout, QLabel, QLineEdit,QListWidget,QToolBox
from qss_login_v3_ui import Ui_Form
from ui_2 import Ui_MainWindowfrom PyQt6 import uic# pyside6-uic.exe ui_2.ui -o ui_2.py
class myWindow(QWidget, Ui_Form): # 多重继承,同时存在QWidget和Ui_Form的功能,这种ui读取方法不可与之前的混用def __init__(self):super().__init__()# 加载ui文件ui = self.setupUi(self) # 用 Ui_Form 类中的 setupUi() 方法,把设计好的 UI 元素(按钮xi、输入框、布局等)挂载到 myWindow 这个 QWidget 实例上。self.pushButton_2.clicked.connect(self.pushButton_2_slot) # 不需要self.pushButton_2:QPushButton = self.pushButton_2,用setupUi已经直接加载到self了,与uic.load不同self.pushButton.clicked.connect(pushButton_slot)def pushButton_2_slot(self):self.close()class window_2(QMainWindow, Ui_MainWindow): # setupUi读取而不是uic.load,因为PySide6和PyQt6存在区别def __init__(self):super().__init__()# 加载ui文件ui = self.setupUi(self) # 用 Ui_Form 类中的 setupUi() 方法,把设计好的 UI 元素(按钮、输入框、布局等)挂载到 myWindow 这个 QWidget 实例上。# 菜单栏# menuBar = self.menuBar()# self.setMenuBar(menu)#工具栏toolBar = QToolBar(self) # 表明从属于selfself.addToolBar(Qt.ToolBarArea.LeftToolBarArea,toolBar) # 表示在self中显示self.menu_btn1 = QPushButton('消息')self.menu_btn2 = QPushButton('联系人')toolBar.addWidget(self.menu_btn1)toolBar.addWidget(self.menu_btn2)self.menu_btn1.clicked.connect(self.show_page1)self.menu_btn2.clicked.connect(self.show_page2)# 创建堆叠布局self.stacked_widget = QStackedWidget()self.init_page1()self.init_page2()# 直接将 QStackedWidget 设置为中心部件self.setCentralWidget(self.stacked_widget)def init_page1(self):page1 = QMainWindow()# 浮动窗口部分page1_docker = QDockWidget(page1)page1.addDockWidget(Qt.DockWidgetArea.LeftDockWidgetArea, page1_docker)# 创建按钮和浮动窗口内容self.dock_btn1 = QPushButton('aaa建材王总')self.dock_btn2 = QPushButton('aaa五金金总')self.dock_btn3 = QPushButton('aaa水果张总')self.dock_btn4 = QPushButton('aaa西兰花李总')self.dock_btn5 = QPushButton('aaa中介小黄')self.dock_btn6 = QPushButton('山本')dock_widget = QWidget()dock_layout = QVBoxLayout()dock_layout.setSpacing(0)dock_layout.setContentsMargins(0, 0, 0, 0)dock_layout.addWidget(self.dock_btn1)dock_layout.addWidget(self.dock_btn2)dock_layout.addWidget(self.dock_btn3)dock_layout.addWidget(self.dock_btn4)dock_layout.addWidget(self.dock_btn5)dock_widget.setLayout(dock_layout)page1_docker.setWidget(dock_widget)# 连接信号self.dock_btn1.clicked.connect(self.switch_chat)self.dock_btn2.clicked.connect(self.switch_chat)self.dock_btn3.clicked.connect(self.switch_chat)self.dock_btn4.clicked.connect(self.switch_chat)self.dock_btn5.clicked.connect(self.switch_chat)# 创建主要组件,用于主题的聊天界面central_widget = QWidget() # 创建中央组件chat_layout = QVBoxLayout()self.page1_top_widget = QLabel("上面的组件 - 占1/8")self.page1_mid_widget = QListWidget()self.page1_bottom_widget = QTextEdit("占3/8")chat_layout.addWidget(self.page1_top_widget)chat_layout.addWidget(self.page1_mid_widget)chat_layout.addWidget(self.page1_bottom_widget)chat_layout.setStretchFactor(self.page1_top_widget, 1)chat_layout.setStretchFactor(self.page1_mid_widget, 4)chat_layout.setStretchFactor(self.page1_bottom_widget, 3)# 设置layout布局到主要组件,然后将主要组件设置到中心组件(mainwindow自带的那个中心组件)central_widget.setLayout(chat_layout)page1.setCentralWidget(central_widget) # 使用setCentralWidget而不是setLayoutself.stacked_widget.addWidget(page1)def init_page2(self):page2 = QMainWindow()page2_toolBox = QToolBox()page2.setCentralWidget(page2_toolBox)# 创建组件并保存引用self.family_list = QListWidget()self.friends_list = QListWidget()self.classmates_list = QListWidget()self.yamamoto_list = QListWidget()# 设置双击跳转信号,该信号会同时传递两个信号,一个是触发信号,一个则是item,在槽函数中需要接收itemself.family_list.itemDoubleClicked.connect(self.page_2_on_item_double_clicked)self.friends_list.itemDoubleClicked.connect(self.page_2_on_item_double_clicked)self.classmates_list.itemDoubleClicked.connect(self.page_2_on_item_double_clicked)self.yamamoto_list.itemDoubleClicked.connect(self.page_2_on_item_double_clicked)# 添加到toolBoxpage2_toolBox.addItem(self.family_list, "家人")page2_toolBox.addItem(self.friends_list, "朋友")page2_toolBox.addItem(self.classmates_list, "同学")page2_toolBox.addItem(self.yamamoto_list, "山本")# 现在可以修改具体的列表self.yamamoto_list.addItem("山本")self.friends_list.addItems(["aaa建材王总","aaa五金金总","aaa水果张总","aaa西兰花李","aaa中介小黄"])self.stacked_widget.addWidget(page2)def show_page1(self):self.stacked_widget.setCurrentIndex(0)def show_page2(self):self.stacked_widget.setCurrentIndex(1)def switch_chat(self):# 获取发送信号的对象sender_btn = self.sender()if sender_btn:btn_text = sender_btn.text()self.page1_top_widget.setText(btn_text)def page_2_on_item_double_clicked(self,item):# """双击联系人跳转到聊天页面并自动点击对应按钮"""# contact_name = item.text()## # 跳转到页面1# self.stacked_widget.setCurrentIndex(0)## # 创建联系人到按钮的映射# contact_to_button = {# "山本一郎": self.dock_btn5,# "山本二郎": self.dock_btn5,# "爸爸": self.dock_btn1, # 假设爸爸对应建材王总# "妈妈": self.dock_btn2, # 假设妈妈对应五金金总# "小明": self.dock_btn3,# "小红": self.dock_btn4,# # 添加更多映射...# }## # 自动点击对应按钮# if contact_name in contact_to_button:# contact_to_button[contact_name].click()# else:# # 如果没有找到对应按钮,可以默认点击第一个# self.dock_btn1.click()print(item.text())#登录按钮
def pushButton_slot(): # 将槽函数设为全局可用而不是某一类下if window.lineEdit.text() == "" and window.lineEdit_2.text() == "":# python基础:window.lineEdit.text()钟text后面要加一个括号是因为这是一个函数,若window.lineEdit.text是一个对象就不需要括号print("匹配成功")window.close()window_2.show()else:print("匹配失败")window.lineEdit.setText("")window.lineEdit_2.setText("")QMessageBox.information(window, "提示", "帐号或密码错误") # window表示父窗口if __name__ == '__main__':app = QApplication(sys.argv)window = myWindow()# 设置纯净窗口(无边框)window.setWindowFlag(Qt.WindowType.FramelessWindowHint)# 去掉窗口多余的空白部分-----------------------------------------------------------------------------------------------window.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)window.show()window_2 = window_2()sys.exit(app.exec())