当前位置:网站首页>Tkinter drawing component (29) -- Radio Group Control

Tkinter drawing component (29) -- Radio Group Control

2022-06-21 21:46:00 Smart-Space

introduction

Actually , Light see TinUI The name of this control ——“ Radio group control ”, Do you think of the previous TinUI Radio buttons ?

in fact , Radio group control (radiobox) Much like radio boxes , Both allow the user to determine a unique option , So that the program can decide what to do . however , Do the two really repeat ? Not always , First look at it. radiobutton Some of the shortcomings of , Or characteristics :

  1. Solidification specifies the single choice case of the problem type

  2. Arrange the layout vertically

  3. Style is TinUI Original style

Of course , The above is not a disadvantage of radio boxes , It can only be said that its specific project . therefore ,radiobutton It is more like an encapsulated control , The radio group control is like a standard control . Of course , They can't replace each other , That's why TinUI add radiobox Control .

It has recently been proposed that radiobutton Add border parameters , And joining add_image function . But I hope you can explain your requirements more clearly , Otherwise I have no way to start , Because I have my own improvement plan .


Layout

Function structure

    def add_radiobox(self,pos:tuple,fontfg='black',font=' Microsoft YaHei  12',fg='#8b8b8b',bg='#ededed',activefg='#898989',activebg='#e5e5e5',onfg='#3041d8',onbg='#ffffff',content:tuple=('1','','2'),padx=10,pady=5,command=None):# Draw radio group control 
        ''' - pos:: Location  - fontfg:: text color  - fg:: Identifier border color  - bg:: Identifier background color  - activefg:: Mouse into the identifier border color  - activebg:: The mouse enters the identifier background color  - onfg:: Select the identifier border color  - onbg:: Select identifier background color  - content:: Choose text content . If it is an empty string, it means newline  - padx:: Horizontal spacing  - pady:: Row spacing  - command:: Callback function , Must accept a parameter , The text of the selected option  '''

Identify fixed elements

The fixed elements here , Include :

  • Identifier normal diameter and border width

  • The diameter and border width when the identifier is activated

  • boxes Dictionaries , The identifier used to place each radio element 、 Text 、 background

  • Currently selected item ( Initialize to -1

        # Identifier internal width width And border width line
        back_width=16
        back_line=1#16+1*2=18
        #active... = back...
        on_width=8
        on_line=4#8+(4+1)*2=18
        boxes=[]#[(sign_id,text_id,back_id),...], Change behavior (None,'\n',None)
        nowx,nowy=pos#x Coordinates are the upper left corner insertion coordinates ,y The coordinates are the bottom coordinates 
        uid='radiobox'+str(id(pos))
        select=-1# Currently selected 
        count=-1
        t_bbox=None

Draw radio elements

These texts are in tuples content in , however , We can't just have horizontal layout , How to make TinUI You know that you should arrange radio elements in a new line ? That is to use empty characters in text tuples . When the string is empty , It means a new line is added . It is worth noting that , When there are currently no radio elements , That is, when there is no text or all empty characters in front , The number of lines on the vertical axis of the next line we add is pady, When there are radio elements in this line , Just add the height of the bank .

        for i in content:
            count+=1# Count 
            if i=='':
                if t_bbox==None:# No bottom coordinate data 
                    nowy+=pady
                else:
                    nowy=t_bbox[3]+pady
                nowx=pos[0]
                boxes.append((None,'\n',None))
                continue
            x1=nowx+back_line
            y1=nowy+back_line
            x2=nowx+back_line+back_width
            y2=nowy+back_line+back_width
            ar=(x1,y1,x2,y2)
            sign=self.create_oval(ar,width=back_line,fill=bg,outline=fg,tags=uid)
            text=self.create_text((x2+5,nowy),text=i,font=font,fill=fontfg,anchor='nw',tags=uid)
            s_bbox=self.bbox(sign)
            t_bbox=self.bbox(text)
            back=self.create_rectangle((s_bbox[0],s_bbox[1],t_bbox[2],t_bbox[3]),width=0,fill='',tags=uid)
            boxes.append((sign,text,back))
            nowx=t_bbox[2]+padx

back Elements are background elements , Its fill color is transparent , But the level is above the identifier element and the text element , So even though we are clicking on a single element , But it's actually a layer over it “ membrane ”, The identifier is only responsible for changing the prompt color . as time goes on , I am right. TinUI The logic of development is continuously optimized >^<.

Mouse in and out

        def button_in(area,sel,sign):
            if sel==select:
                return
            self.itemconfig(sign,outline=activefg,fill=activebg)
        def button_out(area,sel,sign):
            if sel==select:
                return
            self.itemconfig(sign,outline=fg,fill=bg)

There is also a new logic : Record the previous selected item , According to this value , That is to say select Value , Make style changes to the previous selected item , Not like the early days , Find the selected direction by looping . This logic greatly improves the operation efficiency .

Although the early logic code still exists , Yes issue Re reform .

Project selection

        def sel_it(area,sel,sign):
            nonlocal select
            #...

The selection of the project is divided into three logics .

Determine whether the selected item has been :

        def sel_it(area,sel,sign):
            nonlocal select
            if sel==select:
                return

If there is a previous selection , Replace it with the normal style :

            #...
            old_select=select# Serial number of the originally selected item 
            select=sel
            if old_select>=0:# Restore the original radio group 
                old_sign=boxes[old_select][0]
                self.itemconfig(old_sign,width=1)
                button_out(None,None,old_sign)
                self.update()    
            #...

Change the current to the selected identity style :

            self.itemconfig(sign,outline=onfg,fill=onbg,width=on_line)
            if command!=None:
                textid=boxes[sel][1]
                text=self.itemcget(textid,'text')
                command(text)

Binding style :

            self.tag_bind(back,'<Enter>',lambda event,ar=ar,sel=count,sign=sign:button_in(ar,sel,sign))
            self.tag_bind(back,'<Leave>',lambda event,ar=ar,sel=count,sign=sign:button_out(ar,sel,sign))
            self.tag_bind(back,'<Button-1>',lambda event,ar=ar,sel=count,sign=sign:sel_it(ar,sel,sign))

Complete code function

    def add_radiobox(self,pos:tuple,fontfg='black',font=' Microsoft YaHei  12',fg='#8b8b8b',bg='#ededed',activefg='#898989',activebg='#e5e5e5',onfg='#3041d8',onbg='#ffffff',content:tuple=('1','','2'),padx=10,pady=5,command=None):# Draw radio group control 
        def button_in(area,sel,sign):
            if sel==select:
                return
            self.itemconfig(sign,outline=activefg,fill=activebg)
        def button_out(area,sel,sign):
            if sel==select:
                return
            self.itemconfig(sign,outline=fg,fill=bg)
        def sel_it(area,sel,sign):
            nonlocal select
            if sel==select:
                return
            old_select=select# Serial number of the originally selected item 
            select=sel
            if old_select>=0:# Restore the original radio group 
                old_sign=boxes[old_select][0]
                self.itemconfig(old_sign,width=1)
                button_out(None,None,old_sign)
                self.update()
            self.itemconfig(sign,outline=onfg,fill=onbg,width=on_line)
            if command!=None:
                textid=boxes[sel][1]
                text=self.itemcget(textid,'text')
                command(text)
        # Identifier internal width width And border width line
        back_width=16
        back_line=1#16+1*2=18
        #active... = back...
        on_width=8
        on_line=4#8+(4+1)*2=18
        boxes=[]#[(sign_id,text_id,back_id),...], Change behavior (None,'\n',None)
        nowx,nowy=pos#x Coordinates are the upper left corner insertion coordinates ,y The coordinates are the bottom coordinates 
        uid='radiobox'+str(id(pos))
        select=-1# Currently selected 
        count=-1
        t_bbox=None
        for i in content:
            count+=1# Count 
            if i=='':
                if t_bbox==None:# No bottom coordinate data 
                    nowy+=pady
                else:
                    nowy=t_bbox[3]+pady
                nowx=pos[0]
                boxes.append((None,'\n',None))
                continue
            x1=nowx+back_line
            y1=nowy+back_line
            x2=nowx+back_line+back_width
            y2=nowy+back_line+back_width
            ar=(x1,y1,x2,y2)
            sign=self.create_oval(ar,width=back_line,fill=bg,outline=fg,tags=uid)
            text=self.create_text((x2+5,nowy),text=i,font=font,fill=fontfg,anchor='nw',tags=uid)
            s_bbox=self.bbox(sign)
            t_bbox=self.bbox(text)
            back=self.create_rectangle((s_bbox[0],s_bbox[1],t_bbox[2],t_bbox[3]),width=0,fill='',tags=uid)
            boxes.append((sign,text,back))
            self.tag_bind(back,'<Enter>',lambda event,ar=ar,sel=count,sign=sign:button_in(ar,sel,sign))
            self.tag_bind(back,'<Leave>',lambda event,ar=ar,sel=count,sign=sign:button_out(ar,sel,sign))
            self.tag_bind(back,'<Button-1>',lambda event,ar=ar,sel=count,sign=sign:sel_it(ar,sel,sign))
            nowx=t_bbox[2]+padx
        return boxes,uid

effect

Test code

def test8(rbtext):
    print(f' The radio group control selects values =>{
      rbtext}')
if __name__=='__main__':
    #...
    b.add_radiobox((320,1150),content=('1','2','3','',' New line content ','',' The radio ',' Group ',' Control '),command=test8)
    #...

Final effect

 Insert picture description here


github project

TinUI Of github Project address

pip download

pip install tinui

Conclusion

TinUI The next main task is to improve the controls , For the new modules, please send them by email .

tkinter innovation

原网站

版权声明
本文为[Smart-Space]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/172/202206211951435824.html