def disabled_test_getDisplayRectsDoesNotLeak(self): """ Calling L{getDisplayRects} 100,000 times does not leak memory (you'll have to open taskmgr to make sure.) Disabled because Ivan manually confirmed that it does not leak. """ print("Open taskmgr.exe to make sure I'm not leaking memory right now.") for i in xrange(100000): getDisplayRects()
def disabled_test_getDisplayRectsDoesNotLeak(self): """ Calling L{getDisplayRects} 100,000 times does not leak memory (you'll have to open taskmgr to make sure.) Disabled because Ivan manually confirmed that it does not leak. """ print( "Open taskmgr.exe to make sure I'm not leaking memory right now.") for i in range(100000): getDisplayRects()
def image(image_type, monitor): if image_type: screenshot = getRectAsImage(getDisplayRects()[monitor]) return { 'message': 'Screenshot successfully captured', 'screenshot': screenshot, 'text_mode': 'success' } elif not image_type: cam = cv2.VideoCapture(monitor) check, frame = cam.read() if not check: raise Exception('Cam unavailable') frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) frame = Image.fromarray(frame) cam.release() return { 'message': 'Cam screenshot successfully captured', 'screenshot': frame, 'text_mode': 'success' } else: raise Exception('Error message')
def __init__(self, display_number, mode): self._display_number = display_number self._display_rect = getDisplayRects()[self._display_number - 1] self._mode = mode self.buy_back_count = 0 self._result_counter = {"p1": {}, "p2": {}, "p3": {}, "p4": {}}
def Start_buttonOnActivated(self): if (self.meeting_start_hour, self.meeting_end_hour) < (self.meeting_end_hour, self.meeting_end_hour): screens = (getDisplayRects()) rect = getRectAsImage(screens[self.capture_screen]) # 요기 부분은 피드백을 위해 사진을 보여주는 부분이에여 나중에 서버로 전송하면 돼요!! # rect.save() rect.show() print("returned from function capture")
def screenCapture(self): loop = QEventLoop() QTimer.singleShot(self.capture_cycle * 1000, loop.quit) screens = (getDisplayRects()) rect = getRectAsImage(screens[self.capture_screen]) # 요기 부분은 피드백을 위해 사진을 보여주는 부분이에여 나중에 서버로 전송하면 돼요!! # rect.save() rect.show() print("screen captured") loop.exec_()
def get_current_monitor(): x, y = pyautogui.position() monitors = (getDisplayRects()) for monitor in monitors: left, top, right, bottom = monitor if left <= x <= right: if top <= y <= bottom: return Monitor(monitor) return Monitor(monitors[0])
def test_getDisplayRectsReturnsList(self): """ L{getDisplayRects} returns a list of length >= 1 with a tuple containing 4 integers, representing the geometry of each display. """ regions = getDisplayRects() ##print("Display rects are:", regions) self.assertIsInstance(regions, list) for region in regions: self.assertIsInstance(region, tuple) for num in region: self.assertIsInstance(num, int)
def takeScreenShot(self): screen_rectangles = getDisplayRects() numberOfScreens = len(screen_rectangles) screenIndex = min(int(self.state["display_index"].get()) - 1, numberOfScreens) image = getRectAsImage(screen_rectangles[screenIndex]).convert("RGBA") self.state["imageProcessing"] = image self.state["imageProcessing"] = image self.mainCanvasFrame.text.delete("1.0", "end") self.attributes("-fullscreen", True) self.tkimage = ImageTk.PhotoImage(image) self.printScreenFrame.tkraise() self.printScreenFrame.overlayScreenLabel_canvas.config(width=screen_rectangles[screenIndex][0], height=screen_rectangles[screenIndex][1]) self.printScreenFrame.overlayScreenLabel_canvas.create_image(0, 0, anchor="nw", image=self.tkimage)
def sel(): var.get() sel_file = None if os.name == "posix": sel_file = open( os.path.expanduser( "~/Library/Application Support/Colouren/config.json"), 'w') elif os.name == "nt": sel_file = open(os.path.expanduser("~\Colouren\config.json"), 'w') if os.name == "nt" and len(getDisplayRects()) >= 2: Config['display'] = var.get() else: Config['display'] = 1 sel_file.write(json.dumps(Config)) sel_file.close()
def main(addr): bridge = Bridge(addr) senderQ = Queue() senderP = Process(target=senderprocess, args=[bridge, senderQ]) senderP.start() processpool, queuepool = list( zip(*map(lambda x: makeprocess(*x), zip(lights, [senderQ] * regions)))) display = getDisplayRects()[1] # start = time.time() # for _ in range(15): while True: start = time.time() imDisplay = getRectAsImage(display) list(map(lambda x: x.put(imDisplay), queuepool)) sleeptime = 0.2 - (time.time() - start) if sleeptime > 0: time.sleep(sleeptime)
def initialize(): config_dict = utility.get_config_dict() ip = config_dict['ip'] username = config_dict['username'] max_bri = config_dict['max_bri'] min_bri = config_dict['min_bri'] active_lights = [int(i) for i in config_dict['active'].split(',')] all_lights = [int(i) for i in config_dict['all_lights'].split(',')] # Check selected bulbs vs all known bulbs bulb_list = [] for counter, bulb in enumerate(all_lights): if active_lights[counter]: bulb_list.append(active_lights[counter]) else: bulb_list.append(0) bulb_settings = json.loads(config_dict['bulb_settings']) update = config_dict['update'] update_buffer = config_dict['update_buffer'] default = config_dict['default'] zones = ast.literal_eval(config_dict['zones']) zone_state = bool(config_dict['zone_state']) party_mode = bool(config_dict['party_mode']) display_index = config_dict['display_index'] sat = config_dict['sat'] bbox = None if params.BUILD == 'win': from desktopmagic.screengrab_win32 import getDisplayRects bbox = getDisplayRects()[int(display_index)] return ip, username, bulb_list, bulb_settings, default, [], \ update, update_buffer, max_bri, min_bri, zones, zone_state, \ display_index, party_mode, sat, bbox
def getScreenDepthVis(self): #Get screenshot from the second monitotr and crop just the DepthVis for displayNumber, rect in enumerate(getDisplayRects(), 1): if displayNumber == 2: screen = getRectAsImage(rect) screen = np.array(screen) DepthVis = screen[762:1000, 98:525] # NOTE: its img[y: y + h, x: x + w] DepthVis_gray = cv2.cvtColor(DepthVis, cv2.COLOR_BGR2GRAY) small = cv2.resize(DepthVis_gray, (0, 0), fx=0.5, fy=0.5) #cv2.imshow("Test", DepthVis_gray) #cv2.waitKey(0) return DepthVis_gray
def take_screenshot(self, interval, screen_index): if self.screenshot_count == 0: self.screenshot_count = 1 if self.running: file_path = self.entry_folder_select.get() file_name = self.entry_project_name.get() + '_' + str( self.screenshot_count) + '.png' if self.selected_screen.get( ) == 'Screen 1' or self.selected_screen.get() == 'Screen 2': screen = getRectAsImage(getDisplayRects()[screen_index]) screen.save(os.path.join(file_path, file_name), format='png') self.screenshot_count += 1 # ! change interval multiplication back to *60000 self.callbacks.append( self.root.after( interval * self.MILLI_TO_MINS, lambda: self.take_screenshot( int(self.entry_interval.get()), screen_index))) elif self.selected_screen.get() == 'All screens': entire_screen = getScreenAsImage() entire_screen.save(os.path.join(file_path, file_name), format='png') self.screenshot_count += 1 self.callbacks.append( self.root.after( interval * self.MILLI_TO_MINS, lambda: self.take_screenshot( int(self.entry_interval.get()), screen_index))) elif self.selected_screen.get() == 'All screens (separate)': for screen_number, image in enumerate(getDisplaysAsImages(), 1): file_name = self.entry_project_name.get() + '_' + str(self.screenshot_count)\ + '_screen' + str(screen_number) + '.png' image.save(os.path.join(file_path, file_name), format='png') self.screenshot_count += 1 self.callbacks.append( self.root.after( interval * self.MILLI_TO_MINS, lambda: self.take_screenshot( int(self.entry_interval.get()), screen_index)))
def calculate_and_send_packet(): if not Pause: client = udp_client.SimpleUDPClient(Config['ip'], int(Config['port'])) red = 0 green = 0 blue = 0 desktop_image = None if os.name == "nt": desktop_image = getRectAsImage( getDisplayRects()[Config['display'] - 1]) elif os.name == "posix": desktop_image = ImageGrab.grab() if Config['mode'] == 'average': for y in range(0, desktop_image.size[1], Optimisation): for x in range(0, desktop_image.size[0], Optimisation): colour = desktop_image.getpixel((x, y)) red = red + colour[0] green = green + colour[1] blue = blue + colour[2] red = int( round((red / ((desktop_image.size[1] / Optimisation) * (desktop_image.size[0] / Optimisation))), 0)) green = int( round((green / ((desktop_image.size[1] / Optimisation) * (desktop_image.size[0] / Optimisation))), 0)) blue = int( round((blue / ((desktop_image.size[1] / Optimisation) * (desktop_image.size[0] / Optimisation))), 0)) elif Config['mode'] == 'dominant': color_thief = ColorThief(desktop_image) colours = color_thief.get_color(quality=25) red, green, blue = colours try: client.send_message("/red", red) client.send_message("/green", green) client.send_message("/blue", blue) except socket.error: print("Packet Missed") else: return
def main(): print """\ This program constantly polls your display rect information and prints it when it changes. This can be used to make sure getDisplayRects is free from desync bugs that occur during monitor configuration changes. """ lastRects = None count = 0 start = time.time() while True: if count != 0 and count % 1000 == 0: end = time.time() ##print end - start, "for 1000 calls" start = time.time() rects = getDisplayRects() if rects != lastRects: print rects lastRects = rects count += 1
def stream_action(ip, port, resolution, monitor, fps): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ip, port)) headersize = state['settings']['headersize'] encryption = state['settings']['encryption'] encoding = state['settings']['encoding'] mode = [True, 0, b''] while True: last_time = time.time() client_msg = s.recv(81920) if mode[0]: mode[1] = int(client_msg[:headersize]) mode[0] = False mode[2] += client_msg if len(mode[2]) - headersize == mode[1]: frame = getRectAsImage(getDisplayRects()[monitor]) frame = numpy.array(frame) frame = cv2.resize(frame, resolution) frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) if fps: cv2.putText(frame, f'{1.0 / (time.time() - last_time):.2f}', (10, 25), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 0), 2) frame = pickle.dumps(frame) frame = zlib.compress(frame, 9) frame = encryption.do_encrypt(frame) final_msg = bytes(f'{len(frame):<{headersize}}', encoding) + frame s.send(final_msg) mode = [True, 0, b'']
def main(): print("""\ This program constantly polls your display rect information and prints it when it changes. This can be used to make sure getDisplayRects is free from desync bugs that occur during monitor configuration changes. """) lastRects = None count = 0 start = time.time() while True: if count != 0 and count % 1000 == 0: end = time.time() ##print(end - start, "for 1000 calls") start = time.time() rects = getDisplayRects() if rects != lastRects: print(rects) lastRects = rects count += 1
def getDisplayRects(displays): monitors = SGw32.getDisplayRects() # enumerate all displays #print(monitors) #return itemgetter(*displays)(monitors) return [monitors[i] for i in displays]
def device_support(silent, io_channels): device_obj = {} try: device_obj['monitors'] = len(getDisplayRects()) except: device_obj['monitors'] = '???' if silent: device_obj['cams'] = '???' else: cams = [0, []] while True: cam = cv2.VideoCapture(cams[0]) check, frame = cam.read() if not check: break cams[0] += 1 cams[1].append(f'[{int(cam.get(3))},{int(cam.get(4))}]') cam.release() device_obj['cams'] = '{} {}'.format(cams[0], ', '.join(cams[1])) try: p = pyaudio.PyAudio() CHUNK = 81920 FORMAT = pyaudio.paInt16 RATE = 44100 except: device_obj['io-channels'] = '???' else: try: try: stream = p.open(format=FORMAT, channels=2, rate=RATE, input=True, output=False, frames_per_buffer=CHUNK) stream.stop_stream() stream.close() input_channels = '2' except: stream = p.open(format=FORMAT, channels=1, rate=RATE, input=True, output=False, frames_per_buffer=CHUNK) stream.stop_stream() stream.close() input_channels = '1' if io_channels[0] in ('1', '2'): device_obj['io-channels'] = '{}(+), '.format(input_channels) else: device_obj['io-channels'] = '{}(-), '.format(input_channels) except: device_obj['io-channels'] = 'None, ' try: try: stream = p.open(format=FORMAT, channels=2, rate=RATE, input=False, output=True, frames_per_buffer=CHUNK) stream.stop_stream() stream.close() output_channels = '2' except: stream = p.open(format=FORMAT, channels=1, rate=RATE, input=False, output=True, frames_per_buffer=CHUNK) stream.stop_stream() stream.close() output_channels = '1' if io_channels[1] in ('1', '2'): device_obj['io-channels'] += '{}(+)'.format(output_channels) else: device_obj['io-channels'] += '{}(-)'.format(output_channels) except: device_obj['io-channels'] += 'None' p.terminate() return device_obj
def verify_monitor(display): '''Verify the monitor chosen is valid.''' if len(getDisplayRects()) <= display: return True return False
def get_image(self): '''Return an image from a specified display''' display = getDisplayRects()[ self.monitor] # get the dimensions of the monitor return getRectAsImage(display)
def get_primary_monitor() -> Tuple[int, int, int, int]: """ Return the system's default primary monitor rectangle bounds. """ return [rect for rect in getDisplayRects() if rect[:2] == (0, 0)][0] # primary monitor has top left as 0, 0
#!/usr/bin/env/python from desktopmagic.screengrab_win32 import (getDisplayRects, getRectAsImage) import sys, os from PIL import Image from PyQt4 import QtGui numLeds = 32 screens = getDisplayRects() class ScreenColors(QtGui.QWidget): def __init__(self): super(ScreenColors, self).__init__() self.forms = [] self.InitUI() def InitUI(self): #create forms self.squareSize = 25 self.setGeometry(50, 50, 512, 356) for x in range(numLeds): self.forms.append(QtGui.QFrame(self)) self.forms[x].setStyleSheet("QWidget { background-color: %s }" % QtGui.QColor(0,0,0).name()) if x < numLeds / 2:
def get_screens(self): for index, screen in enumerate(getDisplayRects()): self.screen_dict[index] = f'Screen {str(index + 1)}' return self.screen_dict
from desktopmagic.screengrab_win32 import (getDisplayRects, saveScreenToBmp, saveRectToBmp, getScreenAsImage, getRectAsImage, getDisplaysAsImages) # Save the entire virtual screen as a BMP (no PIL required) saveScreenToBmp('screencapture_entire.bmp') # Save an arbitrary rectangle of the virtual screen as a BMP (no PIL required) saveRectToBmp('screencapture_256_256.bmp', rect=(0, 0, 256, 256)) # Save the entire virtual screen as a PNG entireScreen = getScreenAsImage() entireScreen.save('screencapture_entire.png', format='png') # Get bounding rectangles for all displays, in display order print("Display rects are:", getDisplayRects()) # -> something like [(0, 0, 1280, 1024), (-1280, 0, 0, 1024), (1280, -176, 3200, 1024)] # Capture an arbitrary rectangle of the virtual screen: (left, top, right, bottom) rect256 = getRectAsImage((0, 0, 256, 256)) rect256.save('screencapture_256_256.png', format='png') # Unsynchronized capture, one display at a time. # If you need all displays, use getDisplaysAsImages() instead. for displayNumber, rect in enumerate(getDisplayRects(), 1): imDisplay = getRectAsImage(rect) imDisplay.save('screencapture_unsync_display_%d.png' % (displayNumber, ), format='png') # Synchronized capture, entire virtual screen at once, cropped to one Image per display. for displayNumber, im in enumerate(getDisplaysAsImages(), 1):
def body(self, master): self.root_window = master.master.master self.logger = logging.getLogger(self.root_window.logger.name + '.SettingsDisplay') self.k = Keystroke_Watcher(self, sticky=True) # Labels Label(master, text="Avg. Monitor Default: ").grid(row=0, column=0) Label(master, text="Add Preset Color: ").grid(row=1, column=0) Label(master, text="Add keyboard shortcut").grid(row=2, column=0) # Widgets # Avg monitor color match self.avg_monitor = StringVar( master, value=config["AverageColor"]["DefaultMonitor"]) options = [] lst = getDisplayRects() for i in range(1, len(lst) + 1): els = [list(x) for x in itertools.combinations(lst, i)] options.extend(els) self.avg_monitor_dropdown = OptionMenu(master, self.avg_monitor, *lst, 'all') # Custom preset color self.preset_color_name = Entry(master) self.preset_color_name.insert(END, "Enter color name...") self.preset_color_button = Button(master, text="Choose and add!", command=self.get_color) # Add keybindings lightnames = list(self.root_window.lightsdict.keys()) self.keybind_bulb_selection = StringVar(master, value=lightnames[0]) self.keybind_bulb_dropdown = OptionMenu(master, self.keybind_bulb_selection, *lightnames) self.keybind_keys_select = Entry(master) self.keybind_keys_select.insert(END, "Add key-combo...") self.keybind_keys_select.config(state='readonly') self.keybind_keys_select.bind('<FocusIn>', self.on_keybind_keys_click) self.keybind_keys_select.bind( '<FocusOut>', lambda *_: self.keybind_keys_select.config(state='readonly')) self.keybind_color_selection = StringVar(master, value="Color") self.keybind_color_dropdown = OptionMenu( master, self.keybind_color_selection, *self.root_window.framesdict[ self.keybind_bulb_selection.get()].default_colors) self.keybind_add_button = Button( master, text="Add keybind", command=lambda *_: self.register_keybinding( self.keybind_bulb_selection.get(), self.keybind_keys_select.get(), self.keybind_color_selection.get())) self.keybind_delete_button = Button(master, text="Delete keybind", command=self.delete_keybind) # Insert self.avg_monitor_dropdown.grid(row=0, column=1) ttk.Separator(master, orient=HORIZONTAL).grid(row=0, sticky='esw', columnspan=100) self.preset_color_name.grid(row=1, column=1) self.preset_color_button.grid(row=1, column=2) ttk.Separator(master, orient=HORIZONTAL).grid(row=1, sticky='esw', columnspan=100) self.keybind_bulb_dropdown.grid(row=2, column=1) self.keybind_keys_select.grid(row=2, column=2) self.keybind_color_dropdown.grid(row=2, column=3) self.keybind_add_button.grid(row=2, column=4) self.mlb = MultiListbox(master, (('Bulb', 5), ('Keybind', 5), ('Color', 5))) for keypress, fnx in dict(config['Keybinds']).items(): label, color = fnx.split(':') self.mlb.insert(END, (label, keypress, color)) self.mlb.grid(row=3, columnspan=100, sticky='esw') self.keybind_delete_button.grid(row=4, column=0)
def fill_all_screens_geometry(self): #getDisplayRects()-> something like [(0, 0, 1280, 1024), (-1280, 0, 0, 1024), (1280, -176, 3200, 1024)] x_axis, y_axis = self.get_coordinates_for_position(getDisplayRects()) left, top, right, bottom = min(x_axis), min(y_axis), abs(min(x_axis)) + max(x_axis), abs(min(y_axis)) + max(y_axis) self.setGeometry(left, top, right, bottom) return
def get_current_bbox(): return getDisplayRects()[0]
image=desktop_3_image, variable=var, value=3, command=sel) desktop_3_panel.pack(side="top", expand=True) # Radio Button and Labels desktop_1_label = Radiobutton(left_frame, text="Display 1", variable=var, value=1, command=sel, bg='grey') desktop_1_label.pack(side="top") if os.name == "nt" and len(getDisplayRects()) >= 2: desktop_2_label = Radiobutton(middle_frame, text="Display 2", variable=var, value=2, command=sel, bg='grey') else: desktop_2_label = Radiobutton(middle_frame, text="Not Available", variable=var, value=2, command=sel, bg='grey') desktop_2_label.pack(side="top")
def body(self, master): self.root_window = master.master.master # This is really gross. I'm sorry. self.logger = logging.getLogger(self.root_window.logger.name + '.SettingsDisplay') self.key_listener = KeybindManager(self, sticky=True) # Labels Label(master, text="Start Minimized?: ").grid(row=0, column=0) Label(master, text="Avg. Monitor Default: ").grid(row=1, column=0) Label(master, text="Smooth Transition Time (sec): ").grid(row=2, column=0) Label(master, text="Brightness Offset: ").grid(row=3, column=0) Label(master, text="Add Preset Color: ").grid(row=4, column=0) Label(master, text="Audio Input Source: ").grid(row=5, column=0) Label(master, text="Add keyboard shortcut").grid(row=6, column=0) # Widgets # Starting minimized self.start_mini = BooleanVar(master, value=config.getboolean("AppSettings", "start_minimized")) self.start_mini_check = Checkbutton(master, variable=self.start_mini) # Avg monitor color match self.avg_monitor = StringVar(master, value=config["AverageColor"]["DefaultMonitor"]) options = ['full', 'get_primary_monitor', *getDisplayRects()] # lst = getDisplayRects() # for i in range(1, len(lst) + 1): # els = [list(x) for x in itertools.combinations(lst, i)] # options.extend(els) self.avg_monitor_dropdown = OptionMenu(master, self.avg_monitor, *options) self.duration_scale = Scale(master, from_=0, to_=2, resolution=1 / 15, orient=HORIZONTAL) self.duration_scale.set(float(config["AverageColor"]["Duration"])) self.brightness_offset = Scale(master, from_=0, to_=65535, resolution=1, orient=HORIZONTAL) self.brightness_offset.set(int(config["AverageColor"]["brightnessoffset"])) # Custom preset color self.preset_color_name = Entry(master) self.preset_color_name.insert(END, "Enter color name...") self.preset_color_button = Button(master, text="Choose and add!", command=self.get_color) # Audio dropdown device_names = self.master.audio_interface.get_device_names() try: init_string = " " + config["Audio"]["InputIndex"] + " " + device_names[int(config["Audio"]["InputIndex"])] except ValueError: init_string = " None" self.audio_source = StringVar(master, init_string) # AudioSource index is grabbed from [1], so add a space at [0] as_choices = device_names.items() self.as_dropdown = OptionMenu(master, self.audio_source, *as_choices) # Add keybindings lightnames = list(self.root_window.lightsdict.keys()) self.keybind_bulb_selection = StringVar(master, value=lightnames[0]) self.keybind_bulb_dropdown = OptionMenu(master, self.keybind_bulb_selection, *lightnames) self.keybind_keys_select = Entry(master) self.keybind_keys_select.insert(END, "Add key-combo...") self.keybind_keys_select.config(state='readonly') self.keybind_keys_select.bind('<FocusIn>', self.on_keybind_keys_click) self.keybind_keys_select.bind('<FocusOut>', lambda *_: self.keybind_keys_select.config(state='readonly')) self.keybind_color_selection = StringVar(master, value="Color") self.keybind_color_dropdown = OptionMenu(master, self.keybind_color_selection, *self.root_window.framesdict[ self.keybind_bulb_selection.get()].default_colors, *( [*config["PresetColors"].keys()] if any( config["PresetColors"].keys()) else [None]) ) self.keybind_add_button = Button(master, text="Add keybind", command=lambda *_: self.register_keybinding( self.keybind_bulb_selection.get(), self.keybind_keys_select.get(), self.keybind_color_selection.get())) self.keybind_delete_button = Button(master, text="Delete keybind", command=self.delete_keybind) # Insert self.start_mini_check.grid(row=0, column=1) ttk.Separator(master, orient=HORIZONTAL).grid(row=0, sticky='esw', columnspan=100) self.avg_monitor_dropdown.grid(row=1, column=1) self.duration_scale.grid(row=2, column=1) self.brightness_offset.grid(row=3, column=1) ttk.Separator(master, orient=HORIZONTAL).grid(row=3, sticky='esw', columnspan=100) self.preset_color_name.grid(row=4, column=1) self.preset_color_button.grid(row=4, column=2) ttk.Separator(master, orient=HORIZONTAL).grid(row=4, sticky='esw', columnspan=100) self.as_dropdown.grid(row=5, column=1) ttk.Separator(master, orient=HORIZONTAL).grid(row=5, sticky='esw', columnspan=100) self.keybind_bulb_dropdown.grid(row=6, column=1) self.keybind_keys_select.grid(row=6, column=2) self.keybind_color_dropdown.grid(row=6, column=3) self.keybind_add_button.grid(row=6, column=4) self.mlb = MultiListbox(master, (('Bulb', 5), ('Keybind', 5), ('Color', 5))) for keypress, fnx in dict(config['Keybinds']).items(): label, color = fnx.split(':') self.mlb.insert(END, (label, keypress, color)) self.mlb.grid(row=7, columnspan=100, sticky='esw') self.keybind_delete_button.grid(row=8, column=0)