PyQt5的笔记(中-1)

PyQt5的笔记(上)连接:

(1条消息) PyQt5的笔记(上)_我行我素,向往自由的博客-CSDN博客

目录

3.QObject

3.1 继承的父类 

3.2 对象的名称和属性设置-API

3.2.1 API

3.2.2 案例

3.3 父子对象的操作

3.3.1 API 

3.3.2 Qt内存管理机制

3.3.3 应用场景与案例

3.4 信号与槽机制

3.4.1 API

3.4.2 案例

3.5 类型判定

3.5.1 API 

3.5.2 案例

3.6 对象删除

3.7 事件处理

3.8 定时器

3.8.1 API

3.8.2 案例

4.QAbstractButton

4.1 子类化抽象类

4.2 文本设置

4.3 图标相关

4.4 设置快捷键 

4.5 自动重复

4.6 状态读取

4.7 排他性

4.8 模拟点击

4.8.1 代码模拟鼠标点击 

4.8.2 设置点击有效区域

4.9 可用信号

5.QPushButton 

5.1 构造函数

5.2 菜单设置

5.3 扁平化

5.4 默认处理

5.5 右键菜单

6.QCommandLinkButton

7.QToolButton

7.1 创建与基本显示操作 

7.2 工具按钮样式设置

7.3 箭头类型操作

7.4 自动提升功能

7.5 菜单和弹出模式

7.6 可用信号

8.QRadioButton单选框

8.1 创建与基本设置 

8.2 信号使用

8.3 多组互斥问题

9.QButtonGroup

9.1 创建和添加按钮 

9.2 查看按钮

9.3 移除组关系

9.4 绑定和获取ID

9.5 独占操作

9.6 信号使用

10.QCheckBox多选框

10.1 功能使用

10.2 信号

11.QLineEdit

11.1 控件创建、文本的设置获取

11.2 输出模式

11.3 占位文本设置

11.4 清空按钮的设置

11.5 添加自定义行为

11.6 自动补全联想

11.7 输入文本内容限制

11.7.1 长度和只读限制

11.7.2  验证器的使用-设定用户输入规则

11.7.3 掩码限制

11.8 文本修改状态

11.9 光标位置控制

11.10 文本边距设定

11.11 对齐方式 

11.12 常用编辑功能

11.13 信号的使用


3.QObject

3.1 继承的父类 

不同的控件有:

  • 相同的共性:名字、矩形区域、位置、大小、可以设置样式...
  • 不同的特性:展示内容、接收输入、用户交互、容器、框架...

PyQt5的笔记(中-1)_第1张图片

pmros=QObject.mro()
    for mro in mros:
        print(mro)

运行结果:

PyQt5的笔记(中-1)_第2张图片

3.2 对象的名称和属性设置-API

3.2.1 API

PyQt5的笔记(中-1)_第3张图片

# 测试API
obj=QObject()

obj.setObjectName('notice')
print('objectName=',obj.objectName())#notice

#添加属性和值
obj.setProperty('notice_level','error')
obj.setProperty('notice_level','warning')
print('notice_level=',obj.property('notice_level'))#warning
#获取对象中所有通过setProPerty()函数设置的属性名称
print(obj.dynamicPropertyNames())#[PyQt5.QtCore.QByteArray(b'notice_level')]

运行结果:

PyQt5的笔记(中-1)_第4张图片

3.2.2 案例

PyQt5的笔记(中-1)_第5张图片

样式表中的内容如下:  

#QObject.qss文件中的内容
QLabel#notice{
    font-size:20px;
    color:gray;
    border:1px solid gray;
    border-radius:8px;
}
QLabel#notice[notice_level=normal]{
    color:green;
    border-color:green;
}
QLabel#notice[notice_level=warning]{
    color:yellow;
    border-color:yellow;
}
QLabel#notice[notice_level=error]{
    color:red;
    border-color:red;
}

测试代码: 

with open('./QOBject.qss','r') as f:
    qApp.setStyleSheet(f.read())#样式表中能匹配到的样式
    # ==> 同label.setStyleSheet('font-size:20px;color:red;')#样式表
label=QLabel(self)
label.setObjectName('notice')#这个样式可以应用,因为ID是notice
label.setText('正常正常.')

label2 = QLabel(self)
label2.setObjectName('notice')
label2.setProperty('notice_level','warning')
label2.move(100,100)#这个样式也会
label2.setText('警告警告。。。')

label3 = QLabel(self)
label3.setObjectName('no_name')
label3.move(150, 150)  # 这个样式不会,因为名字是no_name,匹配不到
label3.setText('没有名字!')

label4 = QLabel(self)
label4.setObjectName('notice')
label4.setProperty('notice_level','error')
label4.move(200, 200)
label4.setText('错误错误!!!')

btn=QPushButton(self)
btn.setObjectName('notice')
btn.move(50,50)
btn.setText('btn')

#label.setStyleSheet('font-size:20px;color:red;')#样式表

运行结果图:

PyQt5的笔记(中-1)_第6张图片

3.3 父子对象的操作

 

PyQt5的笔记(中-1)_第7张图片

PyQt5的笔记(中-1)_第8张图片

 

3.3.1 API 

obj0 = QObject()
obj1 = QObject()
obj2 = QObject()
obj3 = QObject()
obj4 = QObject()
obj5 = QObject()
print('obj0=', obj0)
print('obj1=', obj1)
print('obj2=', obj2)
print('obj3=', obj3)
print('obj4=', obj4)
print('obj5=', obj5)

obj1.setParent(obj0)  # 设置父类
obj2.setParent(obj0)
obj3.setParent(obj1)
obj4.setParent(obj2)
obj5.setParent(obj2)
# lable=QLabel()
# lable.setParent(obj0)  #报错,不可建立父子关系
# print('lable=',lable)

obj0.setObjectName('0')
obj1.setObjectName('1')
obj2.setObjectName('2')
obj3.setObjectName('3')
obj4.setObjectName('4')
obj5.setObjectName('5')

print('obj0的直接(一级)子类:',obj0.children())
print('obj4的直接(一级)父类:',obj4.parent())
print('obj0找到的QObject类孩子中的第一个:',obj0.findChild(QObject))
print('obj0的儿子obj2:',obj0.findChild(QObject,'2'))
print('obj0的孙子obj3是:', obj0.findChild(QObject,'3'))#这个是可以的【递归/迭代】Qt.FindChildrenRecursively
print('obj0的孙子obj4是(找不到):',obj0.findChild(QObject,'4',Qt.FindDirectChildrenOnly))#只查找直接子对象
print('obj0的所有子子孙孙:',obj0.findChildren(QObject))
    

运行结果:

PyQt5的笔记(中-1)_第9张图片

3.3.2 Qt内存管理机制

PyQt5的笔记(中-1)_第10张图片

obj1=QObject()
self.obj1=obj1
obj2=QObject()
obj2.setParent(obj1)

#监听obj2被释放
obj2.destroyed.connect(lambda :print('obj2被释放了'))

del self.obj1#当父对象被删除时,子对象会被自动释放【当对话框删除时,子窗口也会被释放】

运行结果:

PyQt5的笔记(中-1)_第11张图片

3.3.3 应用场景与案例

PyQt5的笔记(中-1)_第12张图片

PyQt5的笔记(中-1)_第13张图片

app=QApplication(sys.argv)

win1=QWidget()
win1.setStyleSheet('background-color:red;')
win1.setWindowTitle('红色')
win1.show()

win2 = QWidget()
win2.setStyleSheet('background-color:green;')
win2.setParent(win1)#儿子放在父亲里面
win2.resize(100,100)#儿子的窗口大小不可能超过父亲的,父亲会对其进行裁剪
win1.setWindowTitle('绿色')
win2.move(200,200)
win2.show()

sys.exit(app.exec_())

运行效果:

PyQt5的笔记(中-1)_第14张图片

win_root=QWidget()
win_root.resize(500,500)

label1=QLabel(win_root)
label1.setText('label1')


label2 = QLabel(win_root)
label2.setText('label2')
label2.move(50,50)

label3 = QLabel(win_root)
label3.setText('label3')
label3.move(100, 100)

btn=QPushButton(win_root)
btn.move(200,200)
btn.setText('btn')

win_root.show()
for sub_widget in win_root.findChildren(QObject):
    print(sub_widget)
    sub_widget.setStyleSheet('background-color:green')

运行效果图:

PyQt5的笔记(中-1)_第15张图片

PyQt5的笔记(中-1)_第16张图片

3.4 信号与槽机制

PyQt5的笔记(中-1)_第17张图片

PyQt5的笔记(中-1)_第18张图片

3.4.1 API

PyQt5的笔记(中-1)_第19张图片

self.obj=QObject()
#obj.destroyed对象释放时触发
#obj.objectNameChanged对象名字改变时触发

def destroy_cao(obj):
    print('{}对象被释放了...'.format(obj))
self.obj.destroyed.connect(destroy_cao)

def obj_name_cao(name):
    print('对象名称发生了改变:',name)
self.obj.objectNameChanged.connect(obj_name_cao)#connect只是建立连接,但不发出信号
self.obj.setObjectName('xxx')
print('信号是否已经阻断:',self.obj.signalsBlocked(),' 1')#True表示阻断,False表示没有阻断
#self.obj.objectNameChanged.disconnect()#取消名字改变的连接
self.obj.blockSignals(True)#临时阻断信号与槽的连接,
self.obj.setObjectName('ooo')
print('信号是否已经阻断:', self.obj.signalsBlocked(), ' 2')
self.obj.blockSignals(False)#恢复连接
self.obj.setObjectName('xxoo')
print('信号是否已经阻断:', self.obj.signalsBlocked(), ' 3')
del self.obj

运行结果:

PyQt5的笔记(中-1)_第20张图片

一个信号连接多个槽函数代码测试: 

self.obj=QObject()
def obj_name_cao1(name):
    print('对象名字发生改变1:',name)
def obj_name_cao2(name):
    print('对象名字发生改变2:',name)
self.obj.objectNameChanged.connect(obj_name_cao1)#一个信号连接多个槽函数
self.obj.objectNameChanged.connect(obj_name_cao2)

self.obj.setObjectName('xxx')

结果展示:

PyQt5的笔记(中-1)_第21张图片

3.4.2 案例

PyQt5的笔记(中-1)_第22张图片

案例一:

        当用户点击按钮的时候,打印"点我干啥?"

btn=QPushButton(self)
btn.resize(100,50)
btn.move(200,200)
btn.setText('点击我')
def click_cao():
    print('点我干啥?')
btn.clicked.connect(click_cao)

案例一效果图:

 PyQt5的笔记(中-1)_第23张图片

案例二:

要求:

  • 后续我们修改标题为"Hello 张梦姣;最终会自动变为"你真棒!"
  • 支持多次修改

涉及知识点:

  • 设置窗口标题
  • 监听窗口标题改变信号
  • 临时取消/恢复信号与槽的连接
win=QWidget()
win.setWindowTitle('梦之窗')

def title_cao(title):
    print('窗口标题变化了:',title)
    win.windowTitleChanged.disconnect()#或者 win.blockSignals(True)
    win.setWindowTitle(title+' 你真棒!')#不让这句触发槽函数,否则死循环
    win.windowTitleChanged.connect(title_cao)# win.blockSignals(False)

win.windowTitleChanged.connect(title_cao)
win.setWindowTitle('张梦姣')
win.setWindowTitle('李四')

win.show()

运行效果:

PyQt5的笔记(中-1)_第24张图片    

PyQt5的笔记(中-1)_第25张图片

3.5 类型判定

PyQt5的笔记(中-1)_第26张图片

3.5.1 API 

obj=QObject()#False
w=QWidget()#True
btn=QPushButton()#True
label=QLabel()#True

objs=[obj,w,btn,label]
for o in objs:
    print(o.inherits("QWidget")) # <==> print(o.isWidgetType())#判断是否是控件类型

运行结果:

PyQt5的笔记(中-1)_第27张图片

3.5.2 案例

PyQt5的笔记(中-1)_第28张图片

label1=QLabel(self)
label1.setText('label1')
label1.move(100,100)
label2 = QLabel(self)
label2.setText('label2')
label2.move(150, 150)
btn=QPushButton(self)
btn.setText('点我')
btn.move(200, 200)

for widget in  self.children():
    if widget.inherits('QLabel'):
        widget.setStyleSheet('background-color:cyan;')

运行结果: 

PyQt5的笔记(中-1)_第29张图片

3.6 对象删除

 删除对象:是在最后真正删除的,不管是不是在代码中间就手动删除了。

self.obj1=QObject()
self.obj2=QObject()
self.obj3=QObject()
print('obj1:',self.obj1)
print('obj2:',self.obj2)
print('obj3:',self.obj3)
self.obj3.setParent(self.obj2)
self.obj2.setParent(self.obj1)

self.obj1.destroyed.connect(lambda : print('obj1被释放了!'))
self.obj2.destroyed.connect(lambda : print('obj2被释放了!'))
self.obj3.destroyed.connect(lambda : print('obj3被释放了!'))

"""
    deleteLater()并没有将对象立即销毁,而是向主消息循环发送了一个event,
    下一次主消息循环收到这个event之后才会销毁对象。
    好处是可以在这些延迟删除的时间内完成一些操作;
    坏处就是内存释放会不及时。
"""
self.obj2.deleteLater()
#del self.obj2
print(self.obj1.children()) #obj2被释放了,obj1还有孩子

运行结果:

PyQt5的笔记(中-1)_第30张图片

3.7 事件处理

PyQt5的笔记(中-1)_第31张图片

PyQt5的笔记(中-1)_第32张图片

PyQt5的笔记(中-1)_第33张图片

import sys
from PyQt5.Qt import *

class App(QApplication):
    def notify(self,recevier,evt):#重写父类中的notify方法,recevier:事件的接收者,evt:事件本身
        if recevier.inherits('QPushButton') and evt.type()==QEvent.MouseButtonPress:
            print(recevier,evt)
        return super().notify(recevier,evt)

class Btn(QPushButton):
    def event(self,evt):#重写父类中的event
        if evt.type()==QEvent.MouseButtonPress:
            print(evt)
        return super().event(evt)

    def mousePressEvent(self,*args,**kwargs):
        print('鼠标被按下了...')
        return super().mousePressEvent(*args,**kwargs)

app=App(sys.argv)#重写QApplication类,自定义功能
window=QWidget()
btn=Btn(window)
btn.setText('按钮')
btn.move(100,100)
def press_cao():
    print('按钮被点击了!')



btn.pressed.connect(press_cao)

window.show()
sys.exit(app.exec_())

运行结果:

PyQt5的笔记(中-1)_第34张图片

PyQt5的笔记(中-1)_第35张图片

3.8 定时器

PyQt5的笔记(中-1)_第36张图片

3.8.1 API

from PyQt5.Qt import *
import sys

class MyObject(QObject):
    def timerEvent(self,evt):
        print(evt,' 1')


class Window(QWidget):#继承QWidget类
    def __init__(self):
        super().__init__()
        self.setWindowTitle('QObject定时器的使用')
        self.resize(500, 500)
        obj=MyObject(self)
        timer_id=obj.startTimer(1000)#1000毫秒
        obj.killTimer(timer_id)#因为可能会开好几个定时器


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

    window=Window()
    window.show()

    sys.exit(app.exec_())

3.8.2 案例

案例一:设计10秒定时

PyQt5的笔记(中-1)_第37张图片

from PyQt5.Qt import *
import sys

class MyObject(QObject):
    def timerEvent(self,evt):
        print(evt,' 1')

class Mylabel(QLabel):
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        self.setText('10')  # 10秒
        self.move(100, 100)
        self.setStyleSheet('font-size:22px;')

    def setSec(self,sec):
        self.setText(str(sec))

    def startMyTimer(self,ms):
        self.timer_id = self.startTimer(ms)  # 每隔1秒会调用label的timerEvent方法

    def timerEvent(self,*args,**kwargs):#每隔设定时间执行一下timerEvent函数
        #获取当前标签的内容
        current_sec=int(self.text())
        current_sec-=1
        self.setText(str(current_sec))
        if current_sec==0:
            print('时间到!')
            self.killTimer(timer.id)

class Window(QWidget):#继承QWidget类
    def __init__(self):
        super().__init__()
        self.setWindowTitle('QObject定时器案例一')
        self.resize(500, 500)
        label =Mylabel(self)
        label.setSec(10)
        label.startMyTimer(500)#500毫秒


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

    window=Window()
    window.show()

    sys.exit(app.exec_())

运行效果:

PyQt5的笔记(中-1)_第38张图片PyQt5的笔记(中-1)_第39张图片

案例二:通过定时器不断修改窗口尺寸

from PyQt5.Qt import *
import sys

class MyWidget(QWidget):
    def timerEvent(self,*args,**kwargs):
        current_w=self.width()
        current_h=self.height()
        self.resize(current_w+10,current_h+10)

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

    window = MyWidget()
    window.setWindowTitle('定时修改窗口大小')
    window.resize(50,50)
    window.startTimer(100)#每隔100ms会调用timerEvent
    window.show()

    sys.exit(app.exec_())

4.QAbstractButton

PyQt5的笔记(中-1)_第40张图片

PyQt5的笔记(中-1)_第41张图片

PyQt5的笔记(中-1)_第42张图片

4.1 子类化抽象类

不能直接使用抽象类QAbstractButton,需要子类化(如下),或者使用封装的具体类。 

from PyQt5.Qt import *
import sys

class Window(QWidget):#继承QWidget类
    def __init__(self):
        super().__init__()
        self.setWindowTitle('QAbstractButton')
        self.resize(500, 500)

class Btn(QAbstractButton):
    def paintEvent(self,evt):
        print('绘制按钮')
        #绘制按钮上要展示的一个界面内容
        #需要画家、画板、画笔  ==> 画画
        #1 创建一个画家,画在self地方
        painter=QPainter(self)
        #2 给画家一支笔
        #2.1 创建一支笔
        pen=QPen(QColor(110,200,20),5)#QColor:RGB,第二个参数:笔粗细
        #2.2 画家拿着笔
        painter.setPen(pen)
        #3 画家画画
        painter.drawText(25,40,self.text())#点(20,20),内容
        painter.drawEllipse(0,0,100,100)#给一个矩形,画的其实是矩形的内切圆


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

    window=Window()
    btn=Btn(window)
    btn.setText('我是一名高级画师')
    btn.resize(100,100)
    btn.pressed.connect(lambda :print('点击了这个按钮'))
    window.show()

    sys.exit(app.exec_())

4.2 文本设置

PyQt5的笔记(中-1)_第43张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮的功能测试-抽象类')
window.resize(500,500)

btn=QPushButton(window)
btn.setText('1')
#每当点击的时候,数字累加1
def plus_one_cao():
    num=int(btn.text())+1
    btn.setText(str(num))
btn.pressed.connect(plus_one_cao)
window.show()
sys.exit(app.exec_())

点击效果:

PyQt5的笔记(中-1)_第44张图片

4.3 图标相关

PyQt5的笔记(中-1)_第45张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮的功能测试-抽象类')
window.resize(500,500)

btn=QPushButton(window)
btn.move(150,150)
# ***************图标操作***************开始
icon=QIcon('校徽.jpg')
btn.setIcon(icon)
size=QSize(200,200)#宽,高  ==> 把按钮撑大了
btn.setIconSize(size)
#也可以获取信息
print(btn.icon())
print('尺寸大小:',btn.iconSize())
# ***************图标操作***************结束
window.show()
sys.exit(app.exec_())

效果图:

PyQt5的笔记(中-1)_第46张图片

4.4 设置快捷键 

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮的功能测试-抽象类')
window.resize(500,500)

btn=QPushButton(window)
btn.move(150,150)

# # ***************文本操作***************开始
# btn.setText('1')
# #每当点击的时候,数字累加1
# def plus_one_cao():
#     num=int(btn.text())+1
#     btn.setText(str(num))
# btn.pressed.connect(plus_one_cao)
# # ***************文本操作***************结束


# ***************图标操作***************开始
icon=QIcon('校徽.jpg')
btn.setIcon(icon)
size=QSize(200,200)#宽,高  ==> 把按钮撑大了
btn.setIconSize(size)
#也可以获取信息
print(btn.icon())
print('尺寸大小:',btn.iconSize())
# ***************图标操作***************结束


# ***************快捷键的设定***************开始
btn.pressed.connect(lambda : print('按钮被点击了'))

#1.设置文本快捷键
btn.setText('&lbc')#在字符串里的前面加一个&符号  快捷键:alt键+&后面的一个字母l
#当然&符号也可以放中间
btn.setText('a&bc')#快捷键:alt+b   ==>第一种快捷键alt_l被覆盖了,后面的覆盖前面的

#2.可以用图标当作快捷键
btn.setShortcut("alt+q")
# ***************快捷键的设定***************结束

window.show()
sys.exit(app.exec_())

4.5 自动重复

PyQt5的笔记(中-1)_第47张图片

自动重复:就是用户按着按钮不松,就会一直触发。 比如自动开枪一样,点击一直发射。

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮的功能测试-抽象类')
window.resize(500,500)

btn=QPushButton(window)
btn.move(150,150)


# ***************图标操作***************开始
icon=QIcon('子弹.jpg')
btn.setIcon(icon)
size=QSize(200,200)#宽,高  ==> 把按钮撑大了
btn.setIconSize(size)

# ***************图标操作***************结束



# ***************自动重复***************开始
btn.setText('开枪')
btn.pressed.connect(lambda : print('咚咚咚...'))
print(btn.autoRepeat())#此时还没开启自动重复
btn.setAutoRepeat(True)
btn.setAutoRepeatDelay(2000)#检测时延
btn.setAutoRepeatInterval(1000)#自动重复检测检测间隔
# ***************自动重复***************结束

window.show()
sys.exit(app.exec_())

效果图:

PyQt5的笔记(中-1)_第48张图片

4.6 状态读取

PyQt5的笔记(中-1)_第49张图片

PyQt5的笔记(中-1)_第50张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮的功能测试-抽象类')
window.resize(500,500)

btn=QPushButton(window)
btn.setText('总开关【全选/全不选】')
btn.setStyleSheet('font-size:20px;color:green;')
btn.resize(220,50)#宽,高


# ***************状态设定***************开始
push_button=QPushButton(window)
push_button.setText('这是QPushButton')
push_button.move(100,100)

radio_button=QRadioButton(window)
radio_button.setText('这是一个radio')
radio_button.move(100,150)

checkbox=QCheckBox(window)
checkbox.setText('这是一个checkbox')
checkbox.move(100,200)

#1.按下状态
push_button.setStyleSheet('QPushButton:pressed{background-color:red;}')
#把三个按钮都设置为按下状态
push_button.setDown(True)
radio_button.setDown(True)
checkbox.setDown(True)

#2.选中状态
#2.1 isCheckable():表示是否可以被选中,为权限;setCheckable():设定,为状态
print('push_button是否可以被选中:',push_button.isCheckable())#默认是False,但可以通过设定为True
push_button.setCheckable(True)#只是样式不好看,但可以通过setStyleSheet()进行设定
print('radio_button是否可以被选中:',radio_button.isCheckable())#True
print('checkbox是否可以被选中:',checkbox.isCheckable())#True
#2.2 代码选中,setChecked(),为动作
push_button.setChecked(True)
radio_button.setChecked(True)
checkbox.setChecked(True)
#2.3 查看状态isChecked()
print(push_button.isChecked())
print(radio_button.isChecked())
print(checkbox.isChecked())

def cao():
    # push_button.toggle()#切换选中与非选中状态
    # radio_button.toggle()
    # checkbox.toggle()
    #或者
    push_button.setChecked(not push_button.isChecked())
    radio_button.setChecked(not push_button.isChecked())
    checkbox.setChecked(not push_button.isChecked())

btn.pressed.connect(cao)

# ***************状态设定***************结束

window.show()
sys.exit(app.exec_())

效果图:

PyQt5的笔记(中-1)_第51张图片

4.7 排他性

PyQt5的笔记(中-1)_第52张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮的功能测试-抽象类')
window.resize(500,500)
# ***************6.1排他性设置***************开始
for i in range(0,3):
    btn=QPushButton(window)#QPushButton默认不具有排他性
    btn.setText('btn'+str(i))
    btn.move(50*i,50*i)
    btn.setAutoExclusive(True)#设置排他性
    #print(btn.antoExclusive())
    #print(btn.isCheckable())
    btn.setCheckable(True)

btn=QPushButton(window)
btn.setText('btn3')#这个其他三个没有任何关系
btn.move(350,50)
btn.setCheckable(True)

# ***************6.1排他性设置***************结束

# ***************6.2排他性设置***************开始
for i in range(0,3):
    btn=QRadioButton(window)#QRadioButton默认排他性
    btn.setText('btn'+str(i))
    btn.move(50*i+200,50*i+200)

    #取消排他性
    btn.setAutoExclusive(False)
# ***************6.2排他性设置***************结束

window.show()
sys.exit(app.exec_())

运行结果: 

PyQt5的笔记(中-1)_第53张图片

# ***************6.3多选框QCheckBox***************开始
for i in range(0,3):
    btn=QCheckBox(window)#QRadioButton默认排他性
    btn.setText('btn'+str(i))
    btn.move(50*i,50*i)
    #设置排他性
    btn.setAutoExclusive(True)
# ***************6.3多选框QCheckBox***************结束

运行结果: 

PyQt5的笔记(中-1)_第54张图片

4.8 模拟点击

PyQt5的笔记(中-1)_第55张图片

4.8.1 代码模拟鼠标点击 

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮的功能测试-抽象类')
window.resize(500,500)

# ***************7.模拟点击***************开始
btn1=QPushButton(window)
btn1.setText('按钮1')
btn1.move(200,200)
btn1.resize(110,70)
btn1.setStyleSheet('color:green;font-size:20px')
btn1.pressed.connect(lambda : print('点击了按钮1'))
#模拟点击
#btn.click()#点一下就松开了
#btn.animateClick(2000)#相当于鼠标点中按钮不松2s

btn2=QPushButton(window)
btn2.setText('按钮2')
btn2.resize(110,70)
btn2.setStyleSheet('color:red;font-size:20px')
def test():
    #btn1.click()#用按钮2控制按钮1的操作
    btn1.animateClick(2000)
btn2.pressed.connect(test)
# ***************7.模拟点击***************结束

window.show()
sys.exit(app.exec_())

运行效果:

PyQt5的笔记(中-1)_第56张图片

4.8.2 设置点击有效区域

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮的功能测试-抽象类')
window.resize(500,500)

# ***************7.2设置点击区域***************开始
class Btn(QPushButton):
    def hitButton(self,point):
        print('坐标为({},{})'.format(point.x(),point.y()))

        # #点击按钮的左半部分有效,右半部分无效
        # if point.x()>self.width()/2:
        #     return False#返回True表明点point是有效的
        # else:
        #     return True

        #设置内切圆内部有效,外部无效
        yuanxin_x = self.width() / 2
        yuanxin_y = self.height() / 2
        hit_x=point.x()
        hit_y=point.y()
        if ((hit_x-yuanxin_x)**2+(hit_y-yuanxin_y)**2)**0.5 <=self.width() / 2:
            return True
        else:
            return False
    #画内切圆
    def paintEvent(self,evt):
        super().paintEvent(evt)
        painter=QPainter(self)
        painter.setPen(QPen(QColor(100,150,200),6))
        paniter.drawEllipse(self.rect())

btn=Btn(window)
btn.setText('点击')
btn.setStyleSheet('color:red;font-size:40px;')
btn.resize(200,200)
btn.move(150,150)

btn.pressed.connect(lambda :print('按钮被点击了'))
# ***************7.2设置点击区域***************结束

window.show()
sys.exit(app.exec_())

PyQt5的笔记(中-1)_第57张图片

4.9 可用信号

PyQt5的笔记(中-1)_第58张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮的功能测试-抽象类')
window.resize(500,500)

btn=QPushButton(window)
btn.move(100,100)
btn.setText('点击')
btn.resize(200,200)
btn.pressed.connect(lambda:print('按钮被按下了'))
btn.released.connect(lambda:print('按钮鼠标被释放了'))
btn.clicked.connect(lambda value:print('按钮被点击',value))
#切换
btn.toggled.connect(lambda value:print('状态发生了改变:',value))

window.show()
sys.exit(app.exec_())

可以自行测试效果。

5.QPushButton 

PyQt5的笔记(中-1)_第59张图片PyQt5的笔记(中-1)_第60张图片

5.1 构造函数

第一种:按钮和主窗口分开 

from PyQt5.Qt import *
import sys
app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('QPushButton按钮的功能')
window.resize(500,500)
#第一种情况
btn=QPushButton()
btn.setText('按钮')
btn.show()

window.show()
sys.exit(app.exec_())

运行结果1:

PyQt5的笔记(中-1)_第61张图片

第二种:按钮在窗口中

#第二种情况
btn=QPushButton(window)
btn.setText('按钮')
btn.move(200,200)
btn.resize(110,70)


#第三种情况
btn=QPushButton()
btn.setParent(window)
btn.setText('按钮')
btn.move(200,200)
btn.resize(110,70)

运行结果2: 

PyQt5的笔记(中-1)_第62张图片

#显示图片
btn=QPushButton(window)
btn.move(150,150)
icon=QIcon('子弹.jpg')
btn.setIcon(icon)
size=QSize(200,200)#宽,高  ==> 把按钮撑大了
btn.setIconSize(size)#注意:是setIconSize


#显示图片 简洁版
btn=QPushButton(QIcon('子弹.jpg'),'子弹',window)

显示结果3: 

PyQt5的笔记(中-1)_第63张图片

5.2 菜单设置

PyQt5的笔记(中-1)_第64张图片

from PyQt5.Qt import *
import sys
app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('QPushButton按钮的功能')
window.resize(500,500)

# ***************菜单设置***************开始
btn=QPushButton(window)
btn.resize(100,50)
btn.setText('文件操作')
btn.setStyleSheet('background-color:gray;font-size:20px;border:1px solid gray;')
menu=QMenu()#创建菜单
#子菜单:最近打开
open_recent_menu=QMenu(menu)
open_recent_menu.setTitle('最近打开')
#行为动作:新建  打开  分割线  退出
# new_action=QAction()
# new_action.setText('新建')
# new_action.setIcon(QIcon('图片\文件操作icon\新建文件.png'))
new_action=QAction(QIcon('图片\文件操作icon\新建文件.png'),'新建',menu)
new_action.triggered.connect(lambda:print('新建文件'))

open_action=QAction(QIcon('图片\文件操作icon\打开文件.png'),'打开',menu)
open_action.triggered.connect(lambda:print('打开文件'))


exit_action=QAction(QIcon('图片\文件操作icon\退出文件.png'),'退出',menu)
exit_action.triggered.connect(lambda:print('退出程序'))

file_action=QAction('PyQt5')

menu.addAction(new_action)
menu.addAction(open_action)
open_recent_menu.addAction(file_action)
menu.addMenu(open_recent_menu)#添加子菜单
menu.addSeparator()#添加分割线
menu.addAction(exit_action)

btn.setMenu(menu)

window.show()
btn.showMenu()
# ***************菜单设置***************结束


sys.exit(app.exec_())

效果展示:

PyQt5的笔记(中-1)_第65张图片

5.3 扁平化

PyQt5的笔记(中-1)_第66张图片

#扁平化
btn.setFlat(True)#不会绘制按钮背景,除非按下按钮

5.4 默认处理

PyQt5的笔记(中-1)_第67张图片

# ***************默认设置***************开始
btn1=QPushButton(window)
btn1.setText('按钮1')
btn1.move(200,200)
btn1.resize(100,70)

btn2=QPushButton(window)
btn2.setText('按钮2')
btn2.move(350,200)
btn2.resize(100,70)

#设置btn2为默认点下去
# btn2.setAutoDefault(True)#这个方法并不是一运行就是默认,而是用户点击后才为默认
# print('btn1是否设置为默认状态:',btn1.autoDefault())#False
# print('btn2是否设置为默认状态:',btn2.autoDefault())#True

#这个方法才是直接default
btn2.setDefault(True)
# ***************默认设置***************结束

展示效果:

PyQt5的笔记(中-1)_第68张图片

5.5 右键菜单

右键菜单:指的是当用户鼠标右键的时候弹出来的一个菜单。 

# ***************右键菜单***************开始
class Window(QWidget):
    def contextMenuEvent(self,evt):
        pass

window1=Window()
window1.setWindowTitle('右键菜单')
window1.resize(500,500)

def show_menu(point):
    print('自定义上下文菜单:位置({},{})'.format(point.x(),point.y()))
    menu = QMenu(window1)  # 创建菜单
    # 子菜单:最近打开
    open_recent_menu = QMenu(menu)
    open_recent_menu.setTitle('最近打开')
    # 行为动作:新建  打开  分割线  退出
    # new_action=QAction()
    # new_action.setText('新建')
    # new_action.setIcon(QIcon('图片\文件操作icon\新建文件.png'))
    new_action = QAction(QIcon('图片\文件操作icon\新建文件.png'), '新建', menu)
    new_action.triggered.connect(lambda: print('新建文件'))

    open_action = QAction(QIcon('图片\文件操作icon\打开文件.png'), '打开', menu)
    open_action.triggered.connect(lambda: print('打开文件'))

    exit_action = QAction(QIcon('图片\文件操作icon\退出文件.png'), '退出', menu)
    exit_action.triggered.connect(lambda: print('退出程序'))

    file_action = QAction('PyQt5')

    menu.addAction(new_action)
    menu.addAction(open_action)
    open_recent_menu.addAction(file_action)
    menu.addMenu(open_recent_menu)  # 添加子菜单
    menu.addSeparator()  # 添加分割线
    menu.addAction(exit_action)

    # 执行的时候是传递一个point对象,表示展示在哪个位置
    # # exec_();展示函数
    # menu.exec_(evt.globalPos())  # globalPos():这个函数的点是相对于窗口的
    # # menu.exec_(evt.pos())#pos():这个函数的点是相对于桌面的

    menu.exec_(point)#相对于桌面的
    # dest_point=window1.map(point)#映射到全局的
    # menu.exec_(dest_point)


window1.setContextMenuPolicy(Qt.CustomContextMenu)
window1.customContextMenuRequested.connect(show_menu)
window1.show()

# ***************右键菜单***************结束

显示效果:

PyQt5的笔记(中-1)_第69张图片

6.QCommandLinkButton

QCommandLinkButton:命令连接按钮。

PyQt5的笔记(中-1)_第70张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('QCommandLinkButton使用')
window.resize(500,500)

btn=QCommandLinkButton('标题','描述',window)
#修改标题和描述
btn.setText('标题2')
btn.setDescription('描述...')
btn.setIcon(QIcon('图片\点击.png'))
#读取描述内容
print(btn.description())
window.show()
sys.exit(app.exec_())

运行效果:

PyQt5的笔记(中-1)_第71张图片

7.QToolButton

PyQt5的笔记(中-1)_第72张图片

 工具栏中的按钮一般只显示图标,不显示文字。如果既有文本又有图标,默认只显示图标。

7.1 创建与基本显示操作 

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('QToolButton的使用')
window.resize(500,500)
tb=QToolButton(window)
tb.setText('搜索')#区别QPushButton,QPushButton是既显示文本又显示图标
tb.setIcon(QIcon('图片/搜索.png'))#如果既有文本又有图标,默认只显示图标
tb.setIconSize(QSize(60,60))#修改图标大小
tb.setToolTip('这是一个搜索按钮')#提示信息
window.show()
sys.exit(app.exec_())

效果显示:

PyQt5的笔记(中-1)_第73张图片

7.2 工具按钮样式设置

PyQt5的笔记(中-1)_第74张图片

"""
Qt.ToolButtonIconOnly         仅显示图标
Qt.ToolButtonTextOnly         仅显示文本
Qt.ToolButtonTextBesideIcon   文本显示在图标旁边
Qt.ToolButtonTextUnderIcon    文本显示在图标下面
Qt.ToolButtonFollowStyle      遵循风格
"""
tb.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

效果显示:

PyQt5的笔记(中-1)_第75张图片

tb.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)

显示效果:

PyQt5的笔记(中-1)_第76张图片

tb.setToolButtonStyle(Qt.ToolButtonFollowStyle)

效果显示: 

PyQt5的笔记(中-1)_第77张图片

7.3 箭头类型操作

PyQt5的笔记(中-1)_第78张图片

箭头优先级高于图片优先级,高于文本优先级。即如果三者同时出现,会值显示箭头。 

tb=QToolButton(window)
"""
Qt.NoArrow      无箭头
Qt.UpArrow      上箭头
Qt.DownArrow    下箭头
Qt.LeftArrow    左箭头
Qt.RightArrow   右箭头
"""
tb.setArrowType(Qt.NoArrow)

运行效果:

PyQt5的笔记(中-1)_第79张图片

tb.setArrowType(Qt.UpArrow)

运行效果:
PyQt5的笔记(中-1)_第80张图片

tb.setArrowType(Qt.LeftArrow)

运行效果:
PyQt5的笔记(中-1)_第81张图片

tb=QToolButton(window)
tb.setText('箭头')
tb.setArrowType(Qt.LeftArrow)
tb.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

 结果显示:

 PyQt5的笔记(中-1)_第82张图片

7.4 自动提升功能

PyQt5的笔记(中-1)_第83张图片

tb=QToolButton(window)
tb.setText('搜索')#区别QPushButton,QPushButton是既显示文本又显示图标
tb.setIcon(QIcon('图片/搜索.png'))#如果既有文本又有图标,默认只显示图标
tb.setIconSize(QSize(60,60))#修改图标大小
tb.setToolTip('这是一个搜索按钮')#提示信息
tb.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
tb.setAutoRaise(True)#设置扁平化:当鼠标放上去的时候,显示凸起

显示效果:

PyQt5的笔记(中-1)_第84张图片  PyQt5的笔记(中-1)_第85张图片 

7.5 菜单和弹出模式

PyQt5的笔记(中-1)_第86张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('QToolButton的使用')
window.resize(500,500)
tb=QToolButton(window)
tb.setArrowType(Qt.RightArrow)
tb.setText('箭头')
tb.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
btn=QPushButton(window)
btn.setText('一般按钮')
btn.move(100,100)
btn.setFlat(True)
menu=QMenu(btn)
#menu.setTitle('菜单')
sub_menu=QMenu(menu)
sub_menu.setTitle('子菜单')
sub_menu.setIcon(QIcon('图片/文件操作icon/文件.png'))
action=QAction(QIcon('图片/文件操作icon/新建文件.png'),'行为',menu)
action.triggered.connect(lambda :print('点击了行为菜单选项'))
menu.addMenu(sub_menu)
menu.addSeparator()
menu.addAction(action)

tb.clicked.connect(lambda:print('工具按钮被点击了'))
tb.setMenu(menu)
"""
QToolButton.DelayedPopup      鼠标按住一会才显示,类似于浏览器后退按钮
QToolButton.MenuButtonPopup   有一个专门的指示箭头,点击箭头才显示
QToolButton.InstantPopup      点了按钮就显示,点击信号不会发射
"""
tb.setPopupMode(QToolButton.MenuButtonPopup)

window.show()
sys.exit(app.exec_())

运行结果:

PyQt5的笔记(中-1)_第87张图片

7.6 可用信号

PyQt5的笔记(中-1)_第88张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('QToolButton的使用')
window.resize(500,500)
tb=QToolButton(window)
tb.setText('箭头')
tb.setArrowType(Qt.RightArrow)
tb.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
btn=QPushButton(window)
btn.setText('一般按钮')
btn.move(100,100)
btn.setFlat(True)
menu=QMenu(btn)
#menu.setTitle('菜单')
sub_menu=QMenu(menu)
sub_menu.setTitle('子菜单')
sub_menu.setIcon(QIcon('图片/文件操作icon/文件.png'))
action=QAction(QIcon('图片/文件操作icon/新建文件.png'),'新建文件',menu)
action.setData([1,2,3])

action2=QAction(QIcon('图片/文件操作icon/删除文件.png'),'删除文件',menu)
action2.setData({'name':'张'})

action.triggered.connect(lambda :print('点击了新建文件选项'))
menu.addMenu(sub_menu)
menu.addSeparator()
menu.addAction(action)
menu.addAction(action2)
tb.clicked.connect(lambda:print('工具按钮被点击了'))
tb.setMenu(menu)
tb.setPopupMode(QToolButton.MenuButtonPopup)

def do_action(action):
    print('点击了行为',action.data())
tb.triggered.connect(do_action)

window.show()
sys.exit(app.exec_())

结果展示:

PyQt5的笔记(中-1)_第89张图片

8.QRadioButton单选框

PyQt5的笔记(中-1)_第90张图片

用于给用户提供单选操作。 一旦选中一个,会自动取消上次所选按钮。

8.1 创建与基本设置 

PyQt5的笔记(中-1)_第91张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('QradioButton功能测试')
window.resize(500,500)

rb_nan=QRadioButton('男-&Male',window)#设置快捷键:通过快捷键选中 alt+M   ==>或者  rb_nan.setShortcut('alt+m')
rb_nan.move(100,100)
rb_nan.setIcon(QIcon('图片/男.png'))
rb_nan.setIconSize(QSize(60,60))

rb_nv=QRadioButton('女-&Female',window)#alt+F
rb_nv.move(100,170)#上下排
rb_nv.setIcon(QIcon('图片/女.png'))
rb_nv.setIconSize(QSize(60,60))

#设置默认选中
rb_nan.setChecked(True)

window.show()
sys.exit(app.exec_())

运行结果:

PyQt5的笔记(中-1)_第92张图片

8.2 信号使用

PyQt5的笔记(中-1)_第93张图片

PyQt5的笔记(中-1)_第94张图片

常用最后一个切换信号。toggled

#监听切换信号
rb_nv.toggled.connect(lambda isChecked:print(isChecked))#会打印状态,若rb_nv处于选中状态,就是True

#设置两个选项互不影响  即点击的时候不会取消其他的选项
rb_nv.setAutoExclusive(False)

8.3 多组互斥问题

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('QradioButton功能测试')
window.resize(500,500)

#设置两组(男女,对错)互斥
red=QWidget(window)
red.setStyleSheet('background-color:red;')
red.move(50,50)
red.resize(200,200)

green=QWidget(window)
green.setStyleSheet('background:green;')
green.move(red.x()+red.width(),red.y()+red.height())
green.resize(200,200)


rb_nan=QRadioButton('男-&Male',red)
rb_nan.move(70,70)
rb_nan.setChecked(True)

rb_nv=QRadioButton('女-&Female',red)#alt+F
rb_nv.move(70,100)


rb_nan.setChecked(True)

rb_yes=QRadioButton('yes',green)
rb_yes.move(70,70)

rb_no=QRadioButton('no',green)
rb_no.move(70,100)

#默认选中rb_yes
rb_yes.setChecked(True)


window.show()
sys.exit(app.exec_())

运行结果:

PyQt5的笔记(中-1)_第95张图片

9.QButtonGroup

PyQt5的笔记(中-1)_第96张图片

多个按钮划分一组。不具备可视化效果。 

9.1 创建和添加按钮 

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮组的使用')
window.resize(500,500)

#男女
rt_male=QRadioButton('男',window)
rt_male.move(100,100)
rt_female=QRadioButton('女',window)
rt_female.move(100,150)
rt_male.setChecked(True)
#设置一组
sex_group=QButtonGroup(window)
sex_group.addButton(rt_male)
sex_group.addButton(rt_female)

#对错
rt_yes=QRadioButton('对',window)
rt_yes.move(300,100)
rt_no=QRadioButton('错',window)
rt_no.move(300,150)
rt_yes.setChecked(True)
answer_group=QButtonGroup(window)
answer_group.addButton(rt_yes)
answer_group.addButton(rt_no)

window.show()
sys.exit(app.exec_())

效果展示:

PyQt5的笔记(中-1)_第97张图片

9.2 查看按钮

PyQt5的笔记(中-1)_第98张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮组的使用')
window.resize(500,500)


#男女
rt_male=QRadioButton('男',window)
rt_male.move(100,100)
rt_female=QRadioButton('女',window)
rt_female.move(100,150)
rt_male.setChecked(True)
#设置一组
sex_group=QButtonGroup(window)
sex_group.addButton(rt_male,id=1)#指定id,如果id为-1,则将为该按钮分配一个id。自动分配的ID保证为负数,从-2开始。
sex_group.addButton(rt_female,id=2)


print('sex_group组成员:',sex_group.buttons())
print('sex_group组种第一个成员:',sex_group.button(1))
print('sex_group组中被选中多个成员是:',sex_group.checkedButton())


window.show()
sys.exit(app.exec_())

运行效果:

PyQt5的笔记(中-1)_第99张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮组的使用')
window.resize(500,500)

# ***************创建与添加按钮***************开始
#男女
rt_male=QRadioButton('男',window)
rt_male.move(100,100)
rt_female=QRadioButton('女',window)
rt_female.move(100,150)
rt_male.setChecked(True)
#设置一组
sex_group=QButtonGroup(window)
sex_group.addButton(rt_male,id=1)#指定id,如果id为-1,则将为该按钮分配一个id。自动分配的ID保证为负数,从-2开始。
sex_group.addButton(rt_female,id=2)

#对错
rt_yes=QRadioButton('对',window)
rt_yes.move(300,100)
rt_no=QRadioButton('错',window)
rt_no.move(300,150)
rt_yes.setChecked(True)
answer_group=QButtonGroup(window)
answer_group.addButton(rt_yes)
answer_group.addButton(rt_no)
# ***************创建与添加按钮***************结束

# ***************查看按钮***************开始
print('sex_group组成员:',sex_group.buttons())
print('sex_group组种第一个成员:',sex_group.button(1))
print('sex_group组中被选中多个成员是:',sex_group.checkedButton())
# ***************查看按钮***************结束


window.show()
sys.exit(app.exec_())

9.3 移除组关系

PyQt5的笔记(中-1)_第100张图片

移除组关系。并不是移除按钮

#移除组关系
sex_group.removeButton(rt_female)

 运行结果:

PyQt5的笔记(中-1)_第101张图片

9.4 绑定和获取ID

PyQt5的笔记(中-1)_第102张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('按钮组的使用')
window.resize(500,500)

#对错
rt_yes=QRadioButton('对',window)
rt_yes.move(300,100)
rt_no=QRadioButton('错',window)
rt_no.move(300,150)
rt_no.setChecked(True)
answer_group=QButtonGroup(window)
answer_group.addButton(rt_yes)
answer_group.addButton(rt_no)

#绑定ID
answer_group.setId(rt_yes,1)
answer_group.setId(rt_no,2)
#获取ID
print('rt_yes的ID:',answer_group.id(rt_yes))
print('rt_no的ID:',answer_group.id(rt_no))
print('当前选中的id为:',answer_group.checkedId())

window.show()
sys.exit(app.exec_())

运行结果:

PyQt5的笔记(中-1)_第103张图片

9.5 独占操作

PyQt5的笔记(中-1)_第104张图片

#独占操作
answer_group.setExclusive(False)

运行结果:

PyQt5的笔记(中-1)_第105张图片

9.6 信号使用

PyQt5的笔记(中-1)_第106张图片

answer_group.buttonToggled.connect(lambda :print('对错按钮切换'))#这个会打印两次,因为切换是两个操作

def test(val):
    print(answer_group.id(val))#获取id
answer_group.buttonClicked.connect(test)
#或者
sex_group.buttonClicked[int].connect(lambda info:print(info))#过滤出int类型的信息  id

10.QCheckBox多选框

PyQt5的笔记(中-1)_第107张图片

复选框:三种状态,未选中,部分选中,真的被选中。setTristate(True) 

10.1 功能使用

PyQt5的笔记(中-1)_第108张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('QCheckBox功能测试')
window.resize(500,500)

#查看父类
print('QCheckBox的父类:',QCheckBox.__bases__)#QAbstractButton

cb=QCheckBox('&python',window)#快捷键 alt+p  ==> cb.setShortcut('alt+p')
cb.setIcon(QIcon('图片/赞同.png'))
cb.setIconSize(QSize(60,60))

#设置三态
cb.setTristate(True)
print('是否是三态:',cb.isTristate())

#设置复选框状态,因为是三态,所以不可以通过设置True/false来设定
"""  
Qt.Unchecked           未选中
Qt.PartiallyChecked    部分选中
Qt.Checked             选中 
"""
cb.setCheckState(Qt.PartiallyChecked )

window.show()
sys.exit(app.exec_())

运行结果:

PyQt5的笔记(中-1)_第109张图片

10.2 信号

#信号
cb.stateChanged.connect(lambda state:print(state))#打印三种状态0 1 2
cb.toggled.connect(lambda isChecked:print(isChecked))#这个只有True和False,把半选和全选当成一种状态

11.QLineEdit

PyQt5的笔记(中-1)_第110张图片

11.1 控件创建、文本的设置获取

PyQt5的笔记(中-1)_第111张图片

from PyQt5.Qt import *
import sys

app=QApplication(sys.argv)
window=QWidget()
window.setWindowTitle('QLineEdit功能测试')
window.resize(500,500)

print('QLineEdit继承:',QLineEdit.__base__)#QWidget
le=QLineEdit('姓名:',window)#单行文本编辑
#le=QLineEdit('姓名:',window)   ==>  '姓名:'会出现在文本框里作为提示符
"""
setText(str)        设置内容文本
insert(newText)     在光标处插入文本
text()              获取真实内容文本【比如:输入密码的时候,都是点点掩饰,此刻就应该用text()获取,而非displayText】
displayText()       获取用户能看到的内容文本【display()看到什么就获取什么,比如点点】
"""
le.setText('用户名:')
le.setText('年龄:')#此刻会将上行的'用户名:'覆盖
le.insert('20')#会在光标出插入,不会覆盖上述


btn=QPushButton(window)
btn.setText('按钮')
btn.move(100,100)
btn.pressed.connect(lambda :print(le.text()))#获取内容并打印

window.show()
sys.exit(app.exec_())

效果展示:

案例:

le_a=QLineEdit('a:',window)
le_a.move(100,100)
le_a.resize(150,30)

le_b=QLineEdit('b:',window)
le_b.move(100,200)
le_b.resize(150,30)


copy_btn=QPushButton(window)
copy_btn.setText('复制')
copy_btn.move(100,350)
def copy_text():
    print('开始复制......')
    info=le_a.text()
    le_b.setText(info)
copy_btn.pressed.connect(copy_text)

运行结果:

PyQt5的笔记(中-1)_第112张图片

11.2 输出模式

PyQt5的笔记(中-1)_第113张图片

# ***************输出模式设置***************开始
"""
输出模式的几个枚举变量:
    LeadingPosition=0
    NoEcho=1   没有显示【类似于Linux操作系统下的输入密码】
    Normal=0
    Password=2
    PasswordEchoOnEdit=3    编辑的时候是明文,编辑结束后是暗文
    TrailingPosition=1
"""
le_a=QLineEdit('a:',window)
le_a.move(100,100)
le_a.resize(150,30)
le_a.setEchoMode(QLineEdit.Password)

le_b=QLineEdit('b:',window)
le_b.move(100,200)
le_b.resize(150,30)
le_b.setEchoMode(QLineEdit.PasswordEchoOnEdit)

btn_a=QPushButton('按钮a',window)
btn_a.move(70,350)
def cao_a():
    print('读出le_a的Password模式下的内容text()::',print(le_a.text()))
    print('读出le_a的Password模式下的内容displayText()::', print(le_a.displayText()))
btn_a.pressed.connect(cao_a)

btn_b=QPushButton('按钮b',window)
btn_b.move(200,350)
def cao_b():
    print('读出le_b的PasswordEchoOnEdit模式下的内容:',print(le_b.text()))
btn_b.pressed.connect(cao_b)

# ***************输入模式设置***************结束

运行结果:

PyQt5的笔记(中-1)_第114张图片案例:

PyQt5的笔记(中-1)_第115张图片

from PyQt5.Qt import *
import sys

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('登陆界面')
        self.resize(500,500)
        self.setMinimumSize(400, 400)  # 设置最小尺寸,防止拖窗口把几个控件拖没,不好看
        self.setup_ui()


    def setup_ui(self):

        #添加三个控件
        self.account_le=QLineEdit(self)
        self.pwd_le=QLineEdit(self)
        self.pwd_le.setEchoMode(QLineEdit.Password)
        self.login_btn=QPushButton('     登   录     ',self)

        self.login_btn.clicked.connect(self.login_cao)

    def login_cao(self):
        #获取账号信息
        account=self.account_le.text()
        pwd=self.pwd_le.text()
        if account=='root':
            if pwd=='123456':
                print('登陆成功')
            else:
                print('密码错误,请重新输入!')
                self.pwd_le.setText('')
                self.pwd_le.setFocus()#清空后光标仍在该处
        else:
            print('用户名错误!,请重新输入!')
            self.account_le.setText('')
            self.pwd_le.setText('')
            self.account_le.setFocus()

    def resizeEvent(self,evt):
        widget_w = 150  # 每一个控件的宽度
        widget_h = 40  # 每一个控件的高度
        margin = 60  # 每一个控件之间的间距
        self.account_le.resize(widget_w, widget_h)
        self.pwd_le.resize(widget_w, widget_h)
        self.login_btn.resize(widget_w, widget_h)

        # 设置在正中间
        x = int((self.width() - widget_w) / 2)
        self.account_le.move(x, int(self.height() / 5))
        self.pwd_le.move(x, self.account_le.y() + widget_h + margin)
        self.login_btn.move(x, self.pwd_le.y() + widget_h + margin)

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

运行效果:

PyQt5的笔记(中-1)_第116张图片

11.3 占位文本设置

PyQt5的笔记(中-1)_第117张图片

作用:提示用户输入信息。当真正内容输入之后,占位文本就会消失。

#占位文本的提示
self.account_le.setPlaceholderText('请输入账号')
self.pwd_le.setPlaceholderText('请输入密码')

11.4 清空按钮的设置

PyQt5的笔记(中-1)_第118张图片

提供快速删除按钮。 

#设置密码文本框自动快速清空按钮
self.pwd_le.setClearButtonEnabled(True)

效果展示:

PyQt5的笔记(中-1)_第119张图片

11.5 添加自定义行为

PyQt5的笔记(中-1)_第120张图片

在密码输入框后面放一个小眼睛。自己控制明文还是暗文。 

#设置自定义操作(明文密文切换按钮)
action=QAction(self.pwd_le)
action.setIcon(QIcon('图片/闭眼.png'))
def change_cao():
    if self.pwd_le.echoMode()=='Normal':
        self.pwd_le.setEchoMode(QLineEdit.Password)
        action.setIcon(QIcon('图片/比眼.png'))
    else:
        self.pwd_le.setEchoMode(QLineEdit.Normal)
        action.setIcon(QIcon('图片/开眼.png'))
action.triggered.connect(change_cao)
self.pwd_le.addAct

效果展示:

PyQt5的笔记(中-1)_第121张图片

11.6 自动补全联想

PyQt5的笔记(中-1)_第122张图片

completer=QCompleter(['zhang','Zhao','li','Huang','liu'],self.account_le)#指定一个父对象,当父亲被干掉后,儿子也离开
self.account_le.setCompleter(completer)#通过上下键选择,区分大小写

效果展示:

PyQt5的笔记(中-1)_第123张图片

11.7 输入文本内容限制

PyQt5的笔记(中-1)_第124张图片

11.7.1 长度和只读限制

 PyQt5的笔记(中-1)_第125张图片

#文本最大长度限制
le_a.setMaxLength(3)#无论字符还是汉字,最多三个
print('le_a允许输入的最大长度:',le_a.maxLength())

#只读设置
le_a.setReadOnly(False)#True:不允许手动修改    False:允许手动修改, 但都允许代码写入
le_a.setText('12345')

11.7.2  验证器的使用-设定用户输入规则

给用户输入设定规则。 QValidator验证器,三种状态,合法(Acceptable),非法(Invalid),中间状态(Intermediate)。

PyQt5的笔记(中-1)_第126张图片

方式1:判断输入的内容 

from PyQt5.Qt import *
import sys

class AgeVadidator(QValidator):
    def __init__(self):
        super().__init__()
    def validate(self,input_str,pos_int):#input_str:表示输入的内容. pos_int:表示光标的位置
        print(input_str,pos_int)
        #字符串应该都是由数字组成
        try:
            if 18<=int(input_str)<=180:
                # 返回元组数据,  input_str会跑到输入框里面,pos_int控制输入框光标的位置
                return (QValidator.Acceptable, input_str, pos_int)#Acceptable:表明输入的合法的
            elif 0<=int(input_str)<=9:#因为是输入一个数据读取一个数据
                return (QValidator.Intermediate, input_str, pos_int)#Intermediate中间值,不对也不错
            else:
                return (QValidator.Invalid, input_str, pos_int)#Invalid:表明输入的非法的
        except:
            #对空串判定,否则删不掉
            if len(input_str)==0:#表示删掉了输入内容
                return (QValidator.Intermediate, input_str, pos_int)
            return (QValidator.Invalid,input_str,pos_int)
    def fixup(self,p_str):#如果输入为中间状态,就会自动执行这个修复函数
        try:
            if int(p_str)<18:
                return "18"
            else:
                return "180"
        except:
            return '18'

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('QLineEdit验证器的使用')
        self.resize(500,500)
        self.setup_ui()
        
    def setup_ui(self):
        le=QLineEdit(self)
        le.move(100,100)
        #18-180
        vadidator=AgeVadidator()
        le.setValidator(vadidator)


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

方式2:使用系统提供的子类

PyQt5的笔记(中-1)_第127张图片

from PyQt5.Qt import *
import sys

class MyAgeVadidator(QIntValidator):
    def fixup(self,p_str):
        if int(p_str)==0 or int(p_str)<18:#这两个条件不能调换顺序
            return '18'

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('QLineEdit验证器的使用')
        self.resize(500,500)
        self.setup_ui()
        
    def setup_ui(self):
        le=QLineEdit(self)
        le.move(100,100)
        #18-180
        #vadidator=AgeVadidator()
        #使用系统提供的子类
        #vadidator = QIntValidator(18,180)#整形数据的区间验证,QIntValidator功能不完善,所以需要自己写,(下限,上限)
        vadidator = MyAgeVadidator(18, 180)
        le.setValidator(vadidator)


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

11.7.3 掩码限制

PyQt5的笔记(中-1)_第128张图片

未输入之前,用掩码字符占位。

PyQt5的笔记(中-1)_第129张图片

le_a=QLineEdit(window)
le_a.move(100,100)
le_a.resize(150,30)

#设置掩码   [要求:共输入5位,"Cc-dd"]
le_a.setInputMask('>AA-99;#')#当没输入时,用#占位
#座机号掩码:'9999-9999999;0'

运行效果:

PyQt5的笔记(中-1)_第130张图片

11.8 文本修改状态

PyQt5的笔记(中-1)_第131张图片 

le_b=QLineEdit('b:',window)
le_b.move(100,200)
le_b.resize(150,30)

btn=QPushButton('按钮',window)
btn.move(70,350)
def cao():
    print('le_b是否处于编辑状态:',le_b.isModified())
    le_b.setModified(False)#修改状态改为False

btn.pressed.connect(cao)

11.9 光标位置控制

PyQt5的笔记(中-1)_第132张图片

le=QLineEdit(window)
le.move(100,100)

btn=QPushButton(window)
btn.setText('按钮')
btn.move(100,200)
"""
    后——————————————————————>前
    cursorBackward(bool mark,int steps=1)  向后(左)移动steps个字符  mark:带选中效果
    cursorForward(mark,steps)             向前(右)移动
    cursorWordBackward(mark)               向后(左)移动一个单词的距离
    cursorWordForward(mark)                向前(右)移动一个单词的距离
    home(bool mark)                        移动到行首,mark=True带选中效果
    end(bool mark)                         移动到行尾
    setCursorPosition(int)                 设置光标位置
    cursorPositionAt(const QPoint&pos)     获取指定光标位置对应文本光标位置
"""
def cursor_move():
    le.cursorWordBackward(True)#只是移动,并不做其他事情,比如删除
    le.setFocus()
btn.clicked.connect(cursor_move)

11.10 文本边距设定

PyQt5的笔记(中-1)_第133张图片

le=QLineEdit(window)
le.move(100,100)
le.resize(300,300)
#设定文本编剧
#le.setContentsMargins(100,0,0,0)
le.setStyleSheet('background-color:cyan;')
le.setTextMargins(100,200,0,0)

btn=QPushButton(window)
btn.setText('按钮')
btn.move(50,50)

运行效果:

PyQt5的笔记(中-1)_第134张图片 

11.11 对齐方式 

PyQt5的笔记(中-1)_第135张图片

#对其方式设定
le.setAlignment(Qt.AlignRight | Qt.AlignBottom)#同时设定多个对齐方式,按位或

运行效果:

PyQt5的笔记(中-1)_第136张图片

11.12 常用编辑功能

PyQt5的笔记(中-1)_第137张图片

PyQt5的笔记(中-1)_第138张图片  

QLineEdit右键已经提供这些功能。 当然我们作为开发人员,也可以使用提供的API。 

PyQt5的笔记(中-1)_第139张图片 

"""
backspace()         退格,类似于键盘的backspace
del_()              删除
clear()             清空
copy()              复制
cut()               剪切
paste()             粘贴
isUndoAvailable()   撤销   undo()
idRedoAvailable()   重做   redo()
setDragEnabled(bool)拖放  ==>  选中文本后是否可以拖拽
"""
#选中之后再复制,再粘贴
import numpy as np
le.cursorBackward(True,np.random.randint(10))#选中
le.copy()#内容复制到了系统的剪贴板里了
le.setCursorPosition(0)#设置粘贴到哪里
le.paste()

效果展示:

PyQt5的笔记(中-1)_第140张图片

"""
文本选中:
setSelection(start_pos,length)      指定区间选择文本
selectAll()                         选中所有文本
deselect()                          取消选中已选文本
hasSelectedText()                   是否有选中文本
selectedText()     ->str            获取选中文本
selectionStart()   ->int            选中开始位置
selectionEnd()     ->int            选中结束位置
selectionLength()  ->int            选中的长度
"""

11.13 信号的使用

PyQt5的笔记(中-1)_第141张图片

textEdited和textChanged这两个函数,在用户端界面输入时都会触发;
而区别在于代码端能触发textChanged,不会触发textEdited。

# ***************信号的使用***************开始
le_a=QLineEdit(window)
le_a.move(100,100)
le_a.resize(150,30)

#textEdited和textChanged这两个函数,在用户端界面输入时都会触发;
#而区别在于代码端能触发textChanged,不会触发textEdited
le_a.textEdited.connect(lambda val:print('文本框编辑时发生改变:',val))
le_a.textChanged.connect(lambda val:print('文本框内容发生改变:',val))
le_a.setText('kkk')

le_a.returnPressed.connect(lambda:print('回车键被换下'))
#光标位置发生改变触发
le_a.cursorPositionChanged.connect(lambda old_pos,new_pos:print('老位置:{},新位置:{}'.format(old_pos,new_pos)))
#选中文本位置发生改变触发
le_a.selectionChanged.connect(lambda:print('选中文本发生改变'))

# ***************信号的使用***************结束

运行结果:

PyQt5的笔记(中-1)_第142张图片

 

你可能感兴趣的:(Qt知识点,python,PyQt5)