【pyqt5】笔记

主要工具

工具详解
QLabel用于显示文本或图像
QLineEdit允许用户输入一行文本
QTextEdit允许用户输入多行文本
QPushButton一个用于调用动作的命令按钮
QRadioButton可以从多个选项中选择一个。
QCheckBox可以选择一个以上的选项
QSpinBox能够增加/减少一个整数值
QScrollBar可以访问显示孔径以外的小部件的内容。
QSlider能够线性地改变边界值。
QComboBox提供一个可供选择的下拉式项目列表
QMenuBar水平条,用于容纳QMenu对象。
QStatusBar通常在QMainWindow的底部,提供状态信息。
QToolBar通常在QMainWindow的顶部或浮动。包含行动按钮
QListView在ListMode或IconMode中提供一个可选择的项目列表
QPixmap用于显示在QLabel或QPushButton对象上的非屏幕图像表示。
QDialog模态或无模式窗口,可以向父窗口返回信息

dialog、widget、mainwindow的区别

dialog

这个dialog窗口只是为了给人们提供更好的可视化操作,但是对于程序员而言,这个操作并不是立刻执行的;而是当在窗口选择关闭后,才将选择的结果返回给后台,后台才可以根据选择的结果进行相应的操作。
dialog右上角是问号和关闭,它主要用来和用户进行简单交互,比如你安装一个软件会让你点下一步下一步继续安装的,很多是dialog。
有exec函数,如果是dialog窗口,后边的窗口时不可选的;
有show函数

widget

所有用户界面对象的基类。
右上角是缩小放大和退出,是很多简单应用窗口的顶层窗口。
dialog有show函数,如果通过这个函数显示这两种类型的窗口,则两个窗口都是可选的;
主要是在上面放置布局和控件;

mainwindow

有菜单,工具栏,状态栏、托盘等功能。

基本介绍

widget

if __name__ == '__main__':
    app = QApplication(sys.argv)

    w = QWidget()
    w.resize(250, 150)
    w.move(300, 300)
    # 上面两句相当于w.setGeometry(xpos, ypos, width, height)
    w.setWindowTitle('Simple')
    w.setWindowIcon(QIcon('web.png'))
    QToolTip.setFont(QFont('SansSerif', 10))
    w.setToolTip('This is a <b>QWidget</b> widget')
    w.show()

    sys.exit(app.exec_())
  • app:每个PyQt5应用都必须创建一个应用对象。sys.argv是一组命令行参数的列表。Python可以在shell里运行,这个参数提供对脚本控制的功能。
  • QWidge控件是一个用户界面的基本控件,它提供了基本的应用构造器。默认情况下,构造器是没有父级的,没有父级的构造器被称为窗口(window)。
  • exec_:最后,我们进入了应用的主循环中,事件处理器这个时候开始工作。主循环从窗口上接收事件,并把事件派发到应用控件里。当调用exit()方法或直接销毁主控件时,主循环就会结束。sys.exit()方法能确保主循环安全退出。外部环境会收到主控件如何结束的信息。exec_()之所以有个下划线,是因为exec是一个Python的关键字。

自带方法:

  • resize
  • move
  • setGeometry
  • setWindowTitle
  • setWindowIcon
  • setToolTip

其他方法:

def center(self):
    qr = self.frameGeometry()
    cp = QDesktopWidget().availableGeometry().center()
    qr.moveCenter(cp)
    self.move(qr.topLeft())

QPushButton

qbtn = QPushButton('Quit', self)
qbtn.clicked.connect(QCoreApplication.instance().quit)
qbtn.resize(qbtn.sizeHint())
qbtn.move(50, 50) 
用法详解
QPushButton()创建按钮
setText(str)设置按钮显示的文字
move(xpos,ypos)设置按钮距离父组件左上角的距离
resize(w,h)设置按钮的大小
clicked.connect(函数)设置按钮的触发事件

按钮的触发函数:
如果按钮的触发函数式 def test(): ……
括号中只能写test(即函数的名称),例:button.clicked.connext(test)
但是如果遇到需要传参的情况,如 def test(a,b): ……
则可以使用lambda表达式进行传参:例:button.clicked.connext(lambda: test(a,b))

封装了一下:

class Button(QPushButton):
def __init__(self):
    super().__init__()

def add_btn_absolute(self, window, name, location=None, size=None, func=None):
    """
    固定式添加:直接指定按钮的位置(在建立的时候带self)
    @param window: 在QMainWindow的继承类中调用本方法时,直接将self传入
    @param name: 按钮的显示文本
    @param location: 按钮在窗口的位置
    @param size: 按钮的尺寸
    @param func: 按钮的响应函数
    @return: 按钮
    """
    btn = QPushButton(name, window)
    if size:
        btn.resize(size[0], size[1])
    else:
        btn.resize(btn.sizeHint())
    if location:
        btn.move(location[0], location[1])
    if func:
        btn.clicked.connect(func)

def get_btn(self, name, func=None):
    """
    div式添加(不带self)
    @param name: 按钮的显示文本
    @param size: 按钮的尺寸
    @param func: 按钮的响应函数
    @return: 按钮
    """
    btn = QPushButton(name)
    btn.setStyleSheet(''' 
         QPushButton
         {text-align : center;
         background-color : white;
         font: bold;
         border-color: gray;
         border-width: 2px;
         border-style: outset;
         border-radius: 3px;
         padding: 15px;
         margin: 15px;
         font : 14px;}''')
    if func:
        btn.clicked.connect(func)
    return btn

QMessageBox

需要确定型消息可以使用messagebox进行确认,比如关闭前的确认事件。
在widget的重写类中加入以下函数(不用其他语句),就可以在关闭前进行确认。

def closeEvent(self, event):

    reply = QMessageBox.question(self, 
        'Message',
        "Are you sure to quit?", 
        QMessageBox.Yes | QMessageBox.No, 
        QMessageBox.No) # 默认选中no按钮

    if reply == QMessageBox.Yes:
        event.accept()
    else:
        event.ignore() 

底部状态栏。

window.statusBar().showMessage('状态栏显示的文本')

菜单栏

菜单栏结构例子:

def create_menu_bar(window):
    m = MenuBar(window)
    bar = m.create_bar()
    a = m.add_menu(bar, "a")
    b = m.add_action(bar, "b")
    aa = m.add_menu(a, "aa")
    ab = m.add_action(a, "ab")
    ac = m.add_menu(a, "ac")

命令:

  • MenuBar(window)
  • create_bar()
  • add_menu(父组件,要添加的菜单名称)
  • add_action(父组件,要添加的动作名称)

添加动作例子:

# 创建关闭的动作
exitAct = QAction(QIcon('exit.png'), '&Exit', self)
exitAct.setShortcut('Ctrl+Q')
exitAct.setStatusTip('Exit application')
exitAct.triggered.connect(qApp.quit)
# 建立菜单栏
menubar = self.menuBar()
# 将动作加入菜单栏
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(exitAct)
封装
class MenuBar:
    def __init__(self, window):
        self.window = window

    def create_bar(self):
        return self.window.menuBar()

    def add_action(self, parent, son_name):
        son = QAction(son_name, self.window)
        parent.addAction(son)
        return son

    def add_menu(self, parent, son_name):
        son = QMenu(son_name, self.window)
        parent.addMenu(son)
        return son

右键菜单

在window的函数中添加如下代码,可定义右键菜单:

def contextMenuEvent(self, event):
    cmenu = QMenu(self)
    newAct = cmenu.addAction("New")
    opnAct = cmenu.addAction("Open")
    quitAct = cmenu.addAction("Quit")
    action = cmenu.exec_(self.mapToGlobal(event.pos()))

    if action == quitAct:
        qApp.quit()

命令:

  • QMenu(window)
  • addAction(“动作名字”)

布局

封装

class Layout:
    @staticmethod
    def add_layout_to_widget(widget, layout):
        """
        设置窗口布局
        @param widget:窗口
        @param layout: 布局
        """
        widget.setLayout(layout)

    @staticmethod
    def layout_h():
        """
        创建一个水平布局
        @return: 水平布局
        """
        return QHBoxLayout()

    @staticmethod
    def layout_v():
        """
        创建一个垂直布局
        @return: 垂直布局
        """
        return QVBoxLayout()

    @staticmethod
    def add(parent, son):
        """
        将子组件添加到父组件中
        @param parent: 父组件
        @param son: 子组件
        """
        if type(son) == QVBoxLayout or type(son) == QHBoxLayout:
            parent.addLayout(son)
        else:
            parent.addWidget(son)

    @staticmethod
    def set_padding(parent, num):
        parent.addStretch(num)

封装后的命令:

  • layout_h()
  • layout_v()
  • add(parent, son)
  • set_padding(parent, num)
  • add_layout_to_widget(widget, layout) 将当前布局设置为窗口布局

QAction

方法详解
setIcon():设置图标;
setText():设置要显示的文字;
setToolTip():设置提示文字;
setShortcut():设置快捷键;
setCheckable():设置成check选择模式;
setChecked():设置成选中/未选中(菜单前打勾或不打勾)。
信号详解
triggered点击时发射信号
hovered鼠标悬浮上空时发射该信号;
toggled如果状态为选中,则checked为True,该参数会被发送;
changed只要QAction状态发生改变就会发送,如多了个图标,换了文字等。
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QMainWindow, QMenuBar, QMenu, 
                             QAction, QPlainTextEdit, QStyle, QFileDialog,
                             QMessageBox)
 
class DemoNotepad(QMainWindow):
    def __init__(self, parent=None):
        super(DemoNotepad, self).__init__(parent)       
        
        self.setWindowTitle('实战PyQt5: QAction Demo-记事本')      
        self.resize(480, 360)
        self.path = None
        self.initUi()
        
    def initUi(self):
         #设置一个文本编辑器作为中心小部件
        self.txtEditor = QPlainTextEdit(self)  
        self.setCentralWidget(self.txtEditor)
        self.initMenuBar()
       
    def initMenuBar(self):
        menuBar = self.menuBar()       
        fileMenu = menuBar.addMenu('文件(&F)')
        editMenu = menuBar.addMenu('编辑(&E)')
        formatMenu = menuBar.addMenu('格式(&O)')
        helpMenu = menuBar.addMenu('帮助(&H)')
        
        style = QApplication.style()
        
        # ==== 文件操作部分 ==== #
        #新建文件
        aFileNew = QAction('新建(&N)', self)
        #添加一个图标
        aFileNew.setIcon(style.standardIcon(QStyle.SP_FileIcon))
        #添加快捷键
        aFileNew.setShortcut(Qt.CTRL + Qt.Key_N)
        aFileNew.triggered.connect(self.onFileNew)
        fileMenu.addAction(aFileNew)   
        #打开文件
        aFileOpen = QAction('打开(&O)...', self)
        aFileOpen.setIcon(style.standardIcon(QStyle.SP_DialogOpenButton))
        aFileOpen.setShortcut(Qt.CTRL + Qt.Key_O)
        aFileOpen.triggered.connect(self.onFileOpen)
        fileMenu.addAction(aFileOpen)      
        #保存
        aFileSave = QAction('保存(&S)', self) 
        aFileSave.setIcon(style.standardIcon(QStyle.SP_DialogSaveButton)) 
        aFileSave.setShortcut(Qt.CTRL + Qt.Key_S)
        aFileSave.triggered.connect(self.onFileSave)  
        fileMenu.addAction(aFileSave)        
        #另存为
        aFileSaveAs = QAction('另存为(&A)...', self)
        aFileSaveAs.triggered.connect(self.onFileSaveAs)
        fileMenu.addAction(aFileSaveAs)       
        #间隔线
        fileMenu.addSeparator()        
        #退出菜单
        aFileExit = QAction('退出(&X)', self) 
        aFileExit.triggered.connect(self.close)
        fileMenu.addAction(aFileExit)
        
        # ==== 编辑部分 ==== #
        #撤销编辑
        aEditUndo = QAction('撤销(&U)',self)
        aEditUndo.setShortcut(Qt.CTRL + Qt.Key_Z)
        aEditUndo.triggered.connect(self.txtEditor.undo)
        editMenu.addAction(aEditUndo)
        #恢复编辑
        aEditRedo = QAction('恢复(&R)', self)
        aEditRedo.setShortcut(Qt.CTRL + Qt.Key_Y)
        aEditUndo.triggered.connect(self.txtEditor.redo)
        editMenu.addAction(aEditRedo)
        #间隔线
        editMenu.addSeparator()        
        #剪切操作
        aEditCut = QAction('剪切(&T)', self)
        aEditCut.setShortcut(Qt.CTRL + Qt.Key_X)
        aEditCut.triggered.connect(self.txtEditor.cut)
        editMenu.addAction(aEditCut)
        #复制操作
        aEditCopy = QAction('复制(&C)', self)
        aEditCopy.setShortcut(Qt.CTRL + Qt.Key_C)
        aEditCopy.triggered.connect(self.txtEditor.copy)
        editMenu.addAction(aEditCopy)
        #粘贴操作
        aEditPaste = QAction('粘贴(&P)', self)
        aEditPaste.setShortcut(Qt.CTRL + Qt.Key_V)
        aEditPaste.triggered.connect(self.txtEditor.paste)
        editMenu.addAction(aEditPaste)
        #删除操作
        aEditDel = QAction('删除(&L)', self)
        aEditDel.setShortcut(Qt.Key_Delete)
        aEditDel.triggered.connect(self.onEditDelete)
        editMenu.addAction(aEditDel)
        #添加分割线
        editMenu.addSeparator()
        #全选操作
        aEditSelectAll = QAction('全选(&A)', self)
        aEditSelectAll.setShortcut(Qt.CTRL + Qt.Key_A)
        aEditSelectAll.triggered.connect(self.txtEditor.selectAll)
        editMenu.addAction(aEditSelectAll)
        
        # ==== 格式设置部分 ==== #
        aFmtAutoLine = QAction('自动换行(&W)', self)
        aFmtAutoLine.setCheckable(True)
        aFmtAutoLine.setChecked(True)
        aFmtAutoLine.triggered[bool].connect(self.onFormatAutoLine)
        formatMenu.addAction(aFmtAutoLine)
        
        # ==== 帮助部分 ==== #
        aHelpAbout = QAction('关于(&A)...', self)
        aHelpAbout.triggered.connect(self.onHelpAbout)
        helpMenu.addAction(aHelpAbout)
               
    def msgCritical(self, strInfo):
        dlg = QMessageBox(self)
        dlg.setIcon(QMessageBox.Critical)
        dlg.setText(strInfo)
        dlg.show()
        
    def onFileNew(self):
        self.txtEditor.clear()
        
    def onFileOpen(self):
        path,_ = QFileDialog.getOpenFileName(self, '打开文件', '', '文本文件 (*.txt)')
        if path:
            try:
                with open(path, 'rU') as f:
                    text = f.read()
            except Exception as e:
                self.msgCritical(str(e))
            else:
                self.path = path
                self.txtEditor.setPlainText(text)
                
    def onFileSave(self):
        if self.path is None:
            return self.onFileSaveAs()
        self._saveToPath(self.path)
        
    def onFileSaveAs(self):
        path,_ = QFileDialog.getSaveFileName(self, '保存文件', '', '文本文件 (*.txt)')
        if not path:
            return
        self._saveToPath(path)
                
    def _saveToPath(self, path):
        text = self.txtEdit.toPlainText()
        try:
            with open(path, 'w') as f:
                f.write(text)
        except Exception as e:
            self.msgCritical(str(e))
        else:
            self.path = path
            
    def onEditDelete(self):
        tc = self.txtEditor.textCursor()
        #tc.select(QtGui.QTextCursor.BlockUnderCursor) 这样删除一行
        tc.removeSelectedText()
    
    def onFormatAutoLine(self, autoLine):
        if autoLine:
            self.txtEditor.setLineWrapMode(QPlainTextEdit.WidgetWidth)
        else:
            self.txtEditor.setLineWrapMode(QPlainTextEdit.NoWrap)
    
    def onHelpAbout(self):
        QMessageBox.information(self, '实战PyQt5', 'PyQt5实现的文本编辑器演示版')
   
if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = DemoNotepad()
    window.show()
    sys.exit(app.exec()) 

事件与信号

按键

def keyPressEvent(self, e):
    if e.key() == Qt.Key_Escape:
        self.close()

鼠标

def mouseMoveEvent(self, e):
    x = e.x()
    y = e.y()

    text = "x: {0},  y: {1}".format(x, y)
    self.label.setText(text)

完整代码:

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplication, QGridLayout, QLabel

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):      
        grid = QGridLayout()
        grid.setSpacing(10)

        x = 0
        y = 0

        self.text = "x: {0},  y: {1}".format(x, y)

        self.label = QLabel(self.text, self)
        grid.addWidget(self.label, 0, 0, Qt.AlignTop)

        self.setMouseTracking(True)

        self.setLayout(grid)

        self.setGeometry(300, 300, 350, 200)
        self.setWindowTitle('Event object')
        self.show()


    def mouseMoveEvent(self, e):

        x = e.x()
        y = e.y()

        text = "x: {0},  y: {1}".format(x, y)
        self.label.setText(text)


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

按钮
sender返回的值为按钮的文本

def buttonClicked(self):
    sender = self.sender()
    self.statusBar().showMessage(sender.text() + ' was pressed')

对话框

输入框

self.btn.clicked.connect(self.showDialog)
def showDialog(self):

        text, ok = QInputDialog.getText(self, 
        'Input Dialog', 
        'Enter your name:')

        if ok:
            self.le.setText(str(text))

完整代码:

from PyQt5.QtWidgets import (QWidget, QPushButton, QLineEdit, 
    QInputDialog, QApplication)
import sys

class Example(QWidget):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):

        self.btn = QPushButton('Dialog', self)
        self.btn.move(20, 20)
        self.btn.clicked.connect(self.showDialog)

        self.le = QLineEdit(self)
        self.le.move(130, 22)

        self.setGeometry(300, 300, 290, 150)
        self.setWindowTitle('Input dialog')
        self.show()


    def showDialog(self):

        text, ok = QInputDialog.getText(self, 'Input Dialog', 
            'Enter your name:')

        if ok:
            self.le.setText(str(text))


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

选择文件

def showDialog(self):

        fname = QFileDialog.getOpenFileName(self, 'Open file', '/home')

        if fname[0]:
            f = open(fname[0], 'r')

            with f:
                data = f.read()
                self.textEdit.setText(data)

完整代码

#!/usr/bin/python3
# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import (QMainWindow, QTextEdit, 
    QAction, QFileDialog, QApplication)
from PyQt5.QtGui import QIcon
import sys

class Example(QMainWindow):

    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):      

        self.textEdit = QTextEdit()
        self.setCentralWidget(self.textEdit)
        self.statusBar()

        openFile = QAction(QIcon('open.png'), 'Open', self)
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip('Open new File')
        openFile.triggered.connect(self.showDialog)

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(openFile)       

        self.setGeometry(300, 300, 350, 300)
        self.setWindowTitle('File dialog')
        self.show()


    def showDialog(self):

        fname = QFileDialog.getOpenFileName(self, 'Open file', '/home')

        if fname[0]:
            f = open(fname[0], 'r')

            with f:
                data = f.read()
                self.textEdit.setText(data)        

if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())
  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值