将复选框添加到python中的可滚动图像

时间:2019-05-09 09:13:37

标签: python tkinter

基于以下问题的出色答案:Show Large Image using Scrollbar in Python

...我已经能够在Windows Python 3中使用此代码创建可滚动的图像框架。

import tkinter
from PIL import ImageTk, Image

class ScrollableImage(tkinter.Canvas):
    def __init__(self, master=None, **kw):
        self.image = kw.pop('image', None)
        super(ScrollableImage, self).__init__(master=master, **kw)
        self['highlightthickness'] = 0
        self.propagate(0)  # wont let the scrollbars rule the size of Canvas
        self.create_image(0,0, anchor='nw', image=self.image)
        # Vertical and Horizontal scrollbars
        self.v_scroll = tkinter.Scrollbar(self, orient='vertical', width=6)
        self.h_scroll = tkinter.Scrollbar(self, orient='horizontal', width=6)
        self.v_scroll.pack(side='right', fill='y')
        self.h_scroll.pack(side='bottom', fill='x')
        # Set the scrollbars to the canvas
        self.config(xscrollcommand=self.h_scroll.set, 
                yscrollcommand=self.v_scroll.set)
        # Set canvas view to the scrollbars
        self.v_scroll.config(command=self.yview)
        self.h_scroll.config(command=self.xview)
        # Assign the region to be scrolled 
        self.config(scrollregion=self.bbox('all'))

        self.focus_set()
        self.bind_class(self, "<MouseWheel>", self.mouse_scroll)

    def mouse_scroll(self, evt):
        if evt.state == 0 :
            # self.yview_scroll(-1*(evt.delta), 'units') # For MacOS
            self.yview_scroll( int(-1*(evt.delta/120)) , 'units') # For windows
        if evt.state == 1:
            # self.xview_scroll(-1*(evt.delta), 'units') # For MacOS
            self.xview_scroll( int(-1*(evt.delta/120)) , 'units') # For windows

现在,我想添加一行复选框,其中的数字基于给定列表numbers。默认选项应该是选中所有数字。然后可以取消选中某些数字,然后在按下底部时,所有选中的数字应存储在新列表中,即checked_numbers

这是它的样子:

enter image description here

这是我到目前为止尝试过的:

root = tkinter.Tk()


# Creating the check-boxes using a loop
numbers = [3,16,18,22,45]
for ii in numbers:
    var = tkinter.IntVar()
    c = tkinter.Checkbutton(root, text=str(ii), variable=var)
    c.pack()


# PhotoImage from tkinter only supports:- PGM, PPM, GIF, PNG format.
# To use more formats use PIL ImageTk.PhotoImage
img = tkinter.PhotoImage(file='PATH TO IMAGE')

show_image = ScrollableImage(root, image=img, width=400, height=600)
show_image.pack()

这是它的外观:

enter image description here

显然有很多缺陷和我不知道如何实现的事情:

  • 如何在每个循环中分配一个新变量?
  • 如何将所有复选框都排成一行而不是一列?
  • 如何存储已检查的变量?
  • 如何在按下按钮时将检查的变量存储为新列表?

任何帮助将不胜感激!

编辑:

我试图使用@ncica的一个很好的答案,它可以单独很好地工作,并添加了可滚动的图像...

import tkinter as tk
from tkinter import *

root = tk.Tk()


def read_states():
    arry = list(map(lambda var: var.get(), states))  # store which variable has been checked

    checked = []
    result=(zip(numbers,arry))
    for item in result:
        if item[1] == 1:
            checked.append(item[0]) # store the checked variables in a new list "checked"
    print ("Checked are:{}".format(checked))

states = []
numbers = [3,16,18,22,45]
for ii in numbers:
    var = IntVar()
    chk = Checkbutton(root, text=str(ii), variable=var) # assign a new variable in every loop
    chk.grid(row=1,column =numbers.index(ii)) # all checked-boxes put in a row

    states.append(var)
button = tk.Button(root, text='OK', command=read_states)
button.grid(row=1,column =len(numbers)+1)

# PhotoImage from tkinter only supports:- PGM, PPM, GIF, PNG format.
# To use more formats use PIL ImageTk.PhotoImage
img = tk.PhotoImage(file='IMAGE_FILE_PATH')

show_image = ScrollableImage(root, image=img, width=400, height=600)
show_image.pack()



root.mainloop()

...但是出现以下错误:

TclError                                  Traceback (most recent call last)
<ipython-input-11-1556cebf9634> in <module>()
     31 
     32 show_image = ScrollableImage(root, image=img, width=400, height=600)
---> 33 show_image.pack()
     34 
     35 

~\Anaconda3\lib\tkinter\__init__.py in pack_configure(self, cnf, **kw)
   2138         self.tk.call(
   2139               ('pack', 'configure', self._w)
-> 2140               + self._options(cnf, kw))
   2141     pack = configure = config = pack_configure
   2142     def pack_forget(self):

TclError: cannot use geometry manager pack inside . which already has slaves managed by grid

这可以通过将行show_image.pack()替换为show_image.grid(row=2,column =1, columnspan=len(numbers)+1)

来解决。

1 个答案:

答案 0 :(得分:1)

import Tkinter as tk
from Tkinter import *

root = tk.Tk()


def read_states():
    arry = list(map(lambda var: var.get(), states))  # store which variable has been checked

    checked = []
    result=(zip(numbers,arry))
    for item in result:
        if item[1] == 1:
            checked.append(item[0]) # store the checked variables in a new list "checked"
    print ("Checked are:{}".format(checked))

states = []
numbers = [3,16,18,22,45]
for ii in numbers:
    var = IntVar()
    var.set(1) # by default set Checkbuttons as checked
    chk = Checkbutton(root, text=str(ii), variable=var) # assign a new variable in every loop
    chk.grid(row=1,column =numbers.index(ii)) # all checked-boxes put in a row
    states.append(var)

button = tk.Button(root, text='OK', command=read_states) # on button clicked read_states
button.grid(row=1,column =len(numbers)+1) # put button after all Checkbuttons

root.mainloop()

输出:

enter image description here

单击确定按钮,将打印选中的对象