I'm writing a simple application that will play a wav file on one computer based on the message received from the other. I'm using twisted for connection and tkinter for simple gui with buttons.
I'm experienced with neither. As far as I am aware server is working fine when i was using just twisted and sending messages from command line input it was working as expected.
Now that I added gui when I run it both buttons commands execute automatically and they execute once after that i can click them all I want and nothing happens.
Code for client:
from twisted.internet.protocol import Protocol, Factory
from twisted.internet.endpoints import TCP4ClientEndpoint
from twisted.internet import tksupport, reactor, protocol
from tkinter import *
class UI:
def __init__(self, master):
# set up start of screen
self.root = master
# set up frame
self.frame = Frame(self.root, width=80, height=50)
self.frame.pack_propagate(0)
self.frame.pack()
#set up buttons
self._20 = Button(self.frame, text="20", command=self.send_message("20"))
self._20.pack(side=LEFT)
self._30 = Button(self.frame, text="30", command=self.send_message("30"))
self._30.pack(side=RIGHT)
def send_message(self, message):
point = TCP4ClientEndpoint(reactor, "localhost", 2000)
d = point.connect(GreeterFactory())
d.addCallback(lambda p: p.sendMessage(message))
d.addCallback(lambda p: p.transport.loseConnection())
class Greeter(Protocol):
def sendMessage(self, msg):
self.transport.write(msg.encode('utf-8'))
class GreeterFactory(Factory):
def buildProtocol(self, addr):
return Greeter()
# start UI
root = Tk()
root.tk_bisque()
root.title('Q')
root.resizable(width=FALSE, height=FALSE)
ui = UI(root)
tksupport.install(root)
reactor.run()
I expect that after each button press my server will receive message assigned to each button
The thing you pass to command=
needs to be a function. You are not passing a function, you are CALLING a function and passing whatever it returns as the command.
So, your code will call send_message
immediately, during UI.__init__
. send_message
returns None
, so you end up passing command=None
.
You can use lambda
to defer the function call:
#set up buttons
self._20 = Button(self.frame, text="20", command=lambda: self.send_message("20"))
self._20.pack(side=LEFT)
self._30 = Button(self.frame, text="30", command=lambda: self.send_message("30"))
self._30.pack(side=RIGHT)