PyQt5学习(二)

三、VBoxLayout/HBoxLayout/GridLayout练习(完成登录窗口实战)

import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QLabel, 
                            QLineEdit, QPushButton, QMessageBox,
                            QVBoxLayout, QHBoxLayout, QGridLayout)

class LoginWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
        
    def init_ui(self):
        # 主垂直布局
        main_layout = QVBoxLayout()
        
        # 标题区域(水平布局)
        title_layout = QHBoxLayout()
        self.title_label = QLabel('用户登录系统')
        self.title_label.setStyleSheet('font-size: 20px; font-weight: bold;')
        title_layout.addStretch()#在布局开头添加弹性空间,这将推动后续控件向中间靠拢
        title_layout.addWidget(self.title_label)#将标题标签添加到水平布局中
        title_layout.addStretch()#在布局末尾添加弹性空间,与开头配合让标题居中
        main_layout.addLayout(title_layout)#将标题布局添加到主垂直布局当中
        
        # 表单区域(网格布局)
        form_layout = QGridLayout() #网格布局
        form_layout.setSpacing(15)  # 控件间距为15像素
        
        # 用户名行
        self.username_label = QLabel('用户名:')
        self.username_input = QLineEdit()#创建单行文本框
        self.username_input.setPlaceholderText('输入5-16位字母数字')#设置占位文本,提示用户输入格式
        form_layout.addWidget(self.username_label, 0, 0)#将用户名添加到网格布局的第0行第0列
        form_layout.addWidget(self.username_input, 0, 1)#将输入框添加到网格布局的第0行第1列
        
        # 密码行
        self.password_label = QLabel('密码:')
        self.password_input = QLineEdit()
        self.password_input.setPlaceholderText('输入5-16位字符')
        self.password_input.setEchoMode(QLineEdit.Password)
        form_layout.addWidget(self.password_label, 1, 0)
        form_layout.addWidget(self.password_input, 1, 1)
        
        main_layout.addLayout(form_layout) #将网格布局添加到垂直布局中
        
        # 按钮区域(水平布局)
        button_layout = QHBoxLayout()#创建水平布局
        self.login_btn = QPushButton('登录') #创建登陆/取消按钮
        self.cancel_btn = QPushButton('取消')
        button_layout.addStretch()#添加弹性空间,使按钮处于中间状态
        button_layout.addWidget(self.login_btn)#将登陆/取消按钮添加到水平布局中
        button_layout.addWidget(self.cancel_btn)
        button_layout.addStretch()#按钮末尾添加弹性区间,让两个按钮分布在中间位置
        main_layout.addLayout(button_layout)#把水平布局添加到垂直布局中
        
        # 状态栏
        self.status_label = QLabel('准备就绪') #建立状态标签
        self.status_label.setStyleSheet('color: gray;')#设置字体为灰色
        main_layout.addWidget(self.status_label)#将状态标签添加到垂直布局中
        
        # 设置主布局
        self.setLayout(main_layout)#将垂直布局设置为窗口主布局
        self.setWindowTitle('登录演示')#设置主布局的标题
        self.setFixedSize(350, 250)#设置主布局的窗口大小350*250像素
        
        # 信号连接
        self.login_btn.clicked.connect(self.on_login)#将按钮与动作连接
        self.cancel_btn.clicked.connect(self.close)#点击取消关闭窗口
    
    def on_login(self):
        username = self.username_input.text().strip()#获取用户名去除前后空格
        password = self.password_input.text().strip()#获取密码去除前后空格
        
        # 基础校验
        if not username:
            self.status_label.setText('用户名不能为空!')
            return
        if len(username) < 5 or len(username) > 16:
            self.status_label.setText('用户名长度5-16位!')
            return
        if not password:
            self.status_label.setText('密码不能为空!')
            return
        if len(password) < 5 or len(password) > 16:
            self.status_label.setText('密码长度5-16位!')
            return
            
        # 模拟验证
        if username == 'admin' and password == '123456':
            QMessageBox.information(self, '成功', '登录成功!')
            self.status_label.setText('登录成功')
        else:
            QMessageBox.warning(self, '失败', '用户名或密码错误!')
            self.status_label.setText('验证失败')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = LoginWindow()
    window.show()
    sys.exit(app.exec_())

四、QTableWidget数据表格/QComboBox下拉框/QFileDialog文件对话框实战

import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTableWidget, 
                            QTableWidgetItem, QComboBox, QFileDialog,
                            QPushButton, QVBoxLayout, QWidget)

class DemoWindow(QMainWindow):
    def __init__(self): 
        super().__init__()
        
        # 主窗口设置
        self.setWindowTitle("控件演示")
        self.setGeometry(100, 100, 600, 400) #设置窗口位置和大小
        
        # 创建主控件和布局
        central_widget = QWidget()#创建中央控件QWidget()
        self.setCentralWidget(central_widget)#设置为窗口的中央部件
        layout = QVBoxLayout()#使用垂直布局管理器
        
        # 1. QTableWidget示例
        self.table = QTableWidget(3, 3)#创建3行3列的表格
        #设置水平表头,如果设置垂直表头用self.table.setVerticaHeaderLabels()
        self.table.setHorizontalHeaderLabels(["姓名", "年龄", "职业"])
        data = [
            ["张三", "25", "工程师"],
            ["李四", "30", "设计师"],
            ["王五", "28", "教师"]
        ]
        for row in range(3):
            for col in range(3):
        #setItem()方法设置单元格内容,QTableWidgetItem()封装单元格数据
                self.table.setItem(row,col,QTableWidgetItem(data[row][col]))
        
        # 2. QComboBox示例
        self.combo = QComboBox()#创建基础下拉框控件,默认是可编辑状态,用setEditable(False)禁用
        #addItems()批量添加选项列表,addItem()逐个添加选项,添加带图标的选项addItem(QIcon(),"文本")
        self.combo.addItems(["选项1", "选项2", "选项3"])
        #信号在用户选择变化时触发连接到的槽函数
        self.combo.currentIndexChanged.connect(self.on_combo_changed)
        
        # 3. 文件对话框按钮
        self.btn_file = QPushButton("选择文件")#创建按钮
        self.btn_file.clicked.connect(self.open_file_dialog)
        
        # 添加到布局
        layout.addWidget(self.table)
        layout.addWidget(self.combo)
        layout.addWidget(self.btn_file)
        central_widget.setLayout(layout)
    
    def on_combo_changed(self, index):
        print(f"当前选择: {self.combo.currentText()}")
    
    def open_file_dialog(self):
    #返回元组(file_name,selectedFilter),这里用'_'忽略第二个元素。self为制定父窗口,确保对话框模态显示;
    #'选择文件'设置对话框标题文字;""初始目录路径,空字符串表示当前目录;文件过滤器,格式为"描述 (扩展名)",多个过滤器用;;分隔
        file_name,_ = QFileDialog.getOpenFileName(self, "选择文件", "", "所有文件 (*);;文本文件 (*.txt)")
        if file_name:
            print(f"已选择文件: {file_name}")

if __name__ == "__main__":
    app = QApplication(sys.argv) #创建应用实例
    window = DemoWindow() #调用主窗口函数
    window.show()
    sys.exit(app.exec_())

 

posted @ 2025-05-21 15:31  笨笨的小虫子  阅读(16)  评论(0)    收藏  举报