Search code examples
python-3.xtkinterbuttonclickpyautoguipynput

Can I get a function for when I click the mouse a second time (not on the current window)


first off I am new to programming and just learning the basics at the moment. I am creating a 'product picker' using python 3.7 (in pycharm) and want to mouse click on one of the product buttons then on my next mouse click paste/print/insert the product name into my invoicing system.

Currently my code works fine using the 'time' module to set a delay before it types allowing me to select where it is going to type it(line 49 of code). Here is my code:

I have already tried things like onMouseUp or onDoubleClick (i know these are not the correct code but you get the idea).

# import statements import modules
from tkinter import *  # tkinter helps create GUI's
from pynput.keyboard import Key, Controller as keyboardController  # helps 
control keyboard functions
from pynput.mouse import Listener, Controller as mouseController  # helps 
control mouse functions
import time
import pyautogui


# since pynput.mouse and .keyboard have 'Controller' we have to rename them 
so 
both will work
keyboarad = keyboardController()
mouseclick = mouseController()

# defining some variables
root = Tk()
root.grid()
btn = {}
raw_col = 1


# product lists set into categories

product = [
            'product1',
            'product 2',
            'product 3',
            'product 4',
            'product 5'
]


def picker(product):

    time.sleep(3)
    keyboarad.type(product)
    time.sleep(.5)
    keyboarad.press(Key.tab)
    keyboarad.release(Key.tab)
    keyboarad.press(Key.tab)
    keyboarad.release(Key.tab)


# for each 'item in 'raw' list we want you to create a button
for item in product:

    btn[item] = Button(root, text=item, command=lambda x=item: picker(x), 
height=1, width=25)

    btn[item].grid(column=1, row=raw_col, pady=5, padx=5)
     raw_col += 1


mainloop() 

what is actually happening at the moment is it waits 3 seconds then types what i would like it to do is on next click types

Any help would be greatly appreciated, not just to get it working but help me learn.


Solution

  • The command time.sleep(3) suspends the mainloop for three seconds during which it is unresponsive. Try using after() instead as this will schedule an action for later but not suspend the mainloop.

    Update I thing I didn't quite understand what you were after. To print the previous choice at a click you'll have to save the state in some way. In my example I'm simply using a global variable:

    from tkinter import *
    
    root = Tk()
    button_dict = {}
    
    # product lists set into categories
    product_list = ['product 1', 'product 2', 'product 3', 'product 4', 'product 5']
    
    def paste_to_invoice(p):
        # Just to have a function as placeholder for invoicing system
        print('Previous choice was:', p)
    
    last_pick = None    # Global variable to hold previous selection
    def picker(product):
        global last_pick
        if last_pick != None:   # Is there a previous choice?
            paste_to_invoice(last_pick)     # Then print it
        last_pick = product     # Save this choice for next click
    
    # for each 'item in 'raw' list we want you to create a button
    for row, item in enumerate(product_list):
        b = Button(root, text=item, command=lambda x=item: picker(x))
        b.grid(column=1, row=row+1, pady=5, padx=5)
        button_dict[item] = b  # Save reference to button
    
    mainloop()