好友
阅读权限35
听众
最后登录1970-1-1
|
本帖最后由 jumpbull 于 2024-11-1 20:33 编辑
6、单选框(Radiobutton、QRadioButton)
PyQt5 在单选框上的使用就没 tkinter 方便,我先列个对比表,再给代码
类型 | tkinter | PyQt5 | 分组 | 使用 tkinter.IntVar() 变更绑定即可分组 | 需要用 QButtonGroup() 按钮分组对象,再将单选框逐个绑定,代码量多,还好能使用 QtDesigner 在设计时能分组 | 判断选项 | 直接通过绑定的 tkinter.IntVar() 的值进行判断,非常方便 | 可用绑定的按钮分组的按下信号绑定方法槽,通过判断获取单选框的文本来判断,有点不太方便,后面还会给出自定义信号槽的方式来判断(觉得这个方法更合理) | 添加图片 | 支持 | 支持 |
tkinter 代码
[Python] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | self .int_var = tkinter.IntVar()
r1 = tkinter.Radiobutton(box,text = "选项1" ,variable = self .int_var,value = 0 ,command = clickRadiobutton)
r1.pack(side = tkinter.LEFT,padx = 2 )
r2 = tkinter.Radiobutton(box,text = "选项2" ,variable = self .int_var,value = 1 ,command = clickRadiobutton)
r2.pack(side = tkinter.LEFT,padx = 2 )
r3 = tkinter.Radiobutton(box,text = "选项3" ,variable = self .int_var,value = 2 ,command = clickRadiobutton)
r3.pack(side = tkinter.LEFT,padx = 2 )
self .int_var. set ( 1 )
if self .int_var.get() = = 0 :
parint( "我选了第一项" )
elif self .int_var.get() = = 1 :
parint( "我选了第二项" )
else :
parint( "我选了第三项" )
|
PYQt5 代码
判断单选框的选择情况,这里介绍两种方法,各有优缺点,大家自行选择或使用其他方式。一种是利用分组对象的单击信号,可以获得当前所选单选框的文本进行判断,代码简单好理解,但由于要判断文本内容,容易误判,特别是在修改单选框文字时常会忘记同步修改判断代码;另一种通过自定义信号、槽,获取当前选择单选框的序号来判断,缺点是代码量大。下面给出两种方式的代码:
[Python] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | self .radio_button1 = QRadioButton( "选项1" )
self .radio_button2 = QRadioButton( "选项2" )
self .radio_button3 = QRadioButton( "选项3" )
self .button_group = QButtonGroup()
self .button_group.addButton( self .radio_button1)
self .button_group.addButton( self .radio_button2)
self .button_group.addButton( self .radio_button3)
self .layout.addWidget( self .radio_button1)
self .layout.addWidget( self .radio_button2)
self .layout.addWidget( self .radio_button3)
self .button_group.buttonClicked.connect( self .onButtonClicked)
...
def onButtonClicked( self , button):
if button.text() = "选项1" :
...
elif button.text() = "选项2" :
...
else :
...
from PyQt5.QtCore import pyqtSignal
from functools import partial
class main(QMainWindow):
customSignal = pyqtSignal( int )
...
radioButtons = [ self .radio_button1 , self .radio_button2 , self .radio_button3]
for i range ( len (radioButtons)):
radioButtons[i].clicked.connect(partial( self .customSignal.emit , index))
self .customSignal.connect( self .onButtonClicked)
...
def onButtonClicked( self , index):
if index = = 0 :
...
elif index = = 1 :
...
else :
...
|
7、复选框(Checkbutton、QCheckBox)
在 tkinter 中通常绑定 tkinter.intVar() 变量来判断是否为选择状态,而 PyQt5 则是直接用 check.isChecked() 来判断。均支持图片、文本或图片加文本方式出现。PyQt5 中也可以用 QButtonGroup() 给多个复选框分组,相当于把单选框换在复选框的样式,也只能选中其中一个且必须选中一个,意义不大。
tkinter 代码
[Python] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 | self .int_var = tkinter.IntVar()
check = tkinter.Checkbutton(root,text = '选我' ,variable = self .int_var, command = onClickCheck)
check.pack(side = tkinter.LEFT,padx = 3 )
def onClickCheck():
if self .int_var.get():
...
else :
self .int_var. set ( 1 )
|
PYQt5 代码
[Python] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 | self .checkbox = QCheckBox( "同意条款" )
self .checkbox.stateChanged.connect( self .checkbox_changed)
def checkbox_changed( self , state):
if state = = Qt.Checked:
print ( "复选框被勾选" )
else :
print ( "复选框未被勾选" )
if self .checkbox.isChecked() :
print ( "已启用" )
else :
print ( "未启用" )
|
8、多行文本输入框(Text、QTextEdit)
对于这个控制,tkinter 和 PyQt5 对它的操控还是很丰富的,各有特色,都支持富文本显示,总体来说还是 PyQt5 更强一些,这里就对它的一些常用功能进行对比学习
项目 | tkinter | PyQt5 | 尺寸 | 定义时的 width 和 height 属性,注意单位是字符数
text=tkinter.Text(frame, width=30,height=10) | text01.setFixedWidth(150) # 宽度(像素
text01.setFixedHeight(150) # 高度(像素) | 设置文本 | text.delete('1.0' , 'end') # 清空内容
text.insert('end' , '文本内容') | text.setPlainText('文本内容')
或
text.setText('文本内容') | 内容中插入文本 | text.insert('end' , '从最后面插入文本')
text.insert('1.0' , '从最前面插入文本,1表示第1行,0 表示字符位置') | self.text01.append('从最后面追加文本')
其他指定位置插入时,需要用到 QTextCursor 光标对象,代码有点多,见下方演示代码。
或者使用 text.append 插入 html 带格式代码 | 插入富文本 | text.tag_config("样式名",foreground="blue",font=("黑体",12,"bold")) # 设置样式标签
text.insert('end' , "文本内容", “样式名”) # 插入格式文本 | 需要 QTextCursor 光标对象配合使用,代码有点多,见下方演示代码。 | 显示HTML内容 | 不支持 | text.setHtml(html) # html 为网页内容文本
print(text.toHtml()) # 返回文本编辑框中的 HTML 内容 | 插入图片 | text.image_create('end'.image=image) # image 为 PIL 图像数据 | cursor.insertImage("image.jpg") # cursor 为光标对象
或
text.append("<img src=\"image.png\" />") | 插入列表 | 不支持 | tlf = QTextListFormat() # 列表样式对象
tlf.setIndent(2) # 缩进值
tlf.setStyle(QTextListFormat.ListDecimal) #列表样式
cl=cursor.insertList(tlf)
cursor.insertText("项目1\n项目2\n项目3") | 插入表格 | 不支持 | table=cursor.insertTable(2,2) # 插入 2行2列的表格
for row in range(2):
for col in range(2):
cursor.insertText('Cell %d,%d' % (row, col))
cursor.movePosition(cursor.NextCell) | 插入小部件 | 小部件 = tkinter.Button(text,text="确定", command=onClick_OK) # 定义小部件
text.window_create(‘end’.window=小部件) | 不支持 |
PyQt5 光标配合代码
[Python] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | cursor = self .text01.textCursor()
char_format = cursor.charFormat()
char_format.setFontFamily( "Arial" )
char_format.setFontPointSize( 14 )
char_format.setFontWeight(QFont.Bold)
char_format.setFontItalic( True )
char_format.setFontUnderline( True )
cursor.setCharFormat(char_format)
cursor.insertText( "我这富文本" )
cursor.insertImage( "image.jpg" )
def insert_text_at_cursor(textWidget, text, position ,charFormat = None ):
cursor = textWidget.textCursor()
if position = = 'start' or position = = 0 :
cursor.movePosition(cursor.Start)
elif position = = 'end' or position = = - 1 :
cursor.movePosition(cursor.End)
elif isinstance (position, int ):
cursor.movePosition(cursor.Start)
for _ in range (position):
cursor.movePosition(cursor.NextCharacter)
else :
raise ValueError( "position 参数必须是 'start', 'end' 或者一个字符位置整数" )
if charFormat! = None :
cursor.insertText(text , charFormat)
else :
cursor.insertText(text)
textWidget.setTextCursor(cursor)
textWidget.ensureCursorVisible()
def delete_seletion_text(textWidget, start , end):
cursor.setPosition(start)
cursor.setPosition(end,QTextCursor.KeepAnchor)
cursor.removeSelectedText()
self .text.setTextCursor(cursor)
|
9、下拉菜单(Combobox、QComboBox)
tkinter 中下拉菜单提供的功能较弱,不能添加图标,而 PyQt5 可以,判断选择时,tkinter 只能通过项目序或项目文本来判断,PyQt5 还提供了用户数据的判断,比较灵活,它们的示例代码如下:
tkinter 代码
[Python] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | self .combobox = ttk.Combobox( self , width = 15 , state = "readonly" )
self .combobox.pack(side = "left" , padx = 2 )
self .combobox[ 'value' ] = [ '选项1' , '选项2' , '选项3' ]
self .combobox.current( 0 )
self .combobox.bind( "<<ComboboxSelected>>" , self .onChangeItem)
def onChangeItem( self ,event):
print ( self .combobox.get())
if self .combobox.current() = = 0 :
print ( "我选了选项1" )
elif self .combobox.current() = = 1 :
print ( "我选了选项2" )
else :
print ( "我选了选项3" )
|
PYQt5 代码
[Python] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 | self .combobox = QComboBox( self )
self .combobox.addItem( '选项1' , '用户数据1' )
icon = QIcon( 'icon.png' )
self .combobox.addItem(icon, '选项2' , '用户数据2' )
self .combobox.addItems([ "选项 3" , "选项 4" , "选项 5" ])
self .combobox.setEditable( False )
self .combobox.currentIndexChanged.connect( self .combobox_changed)
def combobox_changed( self , index):
text = self .combobox.currentText()
print (f "当前选中: {text}" )
print ( self .combobox.currentData())
|
10、限制范围输入框(Spinbox、QSpinBox)
限制范围输入框右侧带有上、下两调节按键,支持的数据有浮点、整型,tkinter 还支持字符类型的调整,PyQt5 将整型、浮点分成 QSpinBox 和 QDoubleSpinBox 两种控件,不直接支持字符类型,但可以靠自定义类实现。
tkinter 代码
[Python] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 | self .int_var = tkinter.IntVar()
self .str_var = tkinter.StringVar()
spb1 = tkinter.Spinbox(root, from_ = 0 , to = 100 , increment = 1 , textvariable = self .int_var ,
command = self .onClickSpb1)
spb1.pack(side = tkinter.LEFT,padx = 2 )
spb2 = tkinter.Spinbox(root,textvariable = self .str_var , values = ( "项目1" , "项目1" , "项目1" ) ,
state = "readonly" , command = self .onClickSpb2)
spb2.pack(side = tkinter.LEFT,padx = 2 )
self .int_var. set ( 5 )
def onClickSpb1( self ):
print ( self .int_var.get())
|
PYQt5 代码
[Python] 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | self .spin = QSpinBox( self )
self .spin.setRange( 0 , 500 )
self .spin.setValue( 50 )
self .spin.setSingleStep( 2 )
self .spin.setDecimals( 2 )
spb.setWrapping( True )
self .spin.setReadOnly( True )
self .spin.setPrefix( "$" )
self .spin.setSuffix( ".00" )
self .spin.valueChanged.connect( self .handle_spin)
def handle_spin( self , i):
print (i)
|
实现字符枚举的演示
[Python] 纯文本查看 复制代码 1 2 3 4 5 6 7 8 9 | class strSpinBox(QSpinBox):
def textFromValue( self , v: int ):
week = [ '星期日' , '星期一' , '星期二' , '星期三' , '星期四' , '星期五' , '星期六' , ]
return week[v]
...
self .mySpinbox = strSpinBox()
self .mySpinbox.setRange( 0 , 6 )
|
|
|