supra
Posts: 751
Joined: Thu Feb 28, 2013 9:21 am
Location: Ontario, Canada

tkinter How to pass entry to another module?

Mon Oct 23, 2017 12:47 pm

How to pass tkinter entry to another module? I am working on irc chat similar to pirch.
The problem is I can't get string from entry.
Here is server_channel:

Code: Select all

#!/usr/bin/python 3.6
from tkinter import *

root = Tk()
v = StringVar()
text1 = Text(root, height=25, width=125, bg='black', fg='yellow')
scroll = Scrollbar(root, command=text1.yview, orient=VERTICAL)
scroll.config(command=text1.yview)
text1.configure(yscrollcommand=scroll.set)
entry = Entry(root, textvariable = v, bg='white', fg='black')
entry.pack(side = BOTTOM, fill=BOTH)
entry.focus()
text1.pack(side=LEFT, fill=BOTH, expand='YES')
scroll.pack(side=RIGHT, fill=BOTH)

def server_get(event):
    p =(entry.get())
    data = (str(p).split('/')[1])
    entry.delete(0, END)
entry.bind('<Return>', server_get)

def main():
    root.mainloop()
Here is irc_connection:

Code: Select all

import socket, sys, threading, time
from tkinter import *
import server_channel
class IRC_Server:
     def __init__(self, host, port, nick, channel, password =""):
        self.irc_host = host
        self.irc_port = port
        self.irc_nick = nick
        self.irc_channel = channel
        self.irc_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.is_connected = False
        self.should_reconnect = False
        self.command = ""
         
     def connect(self):
         :
         :
         :
         self.proceed_command(server_channel.entry.get())
         
         self.is_connected = True         
         self.listen()

     def proceed_command(self, data):
        command = data#.split()[0]
        
        if command == 'whois':
            _nick = data.split()[1]
            _WHOIS = ("WHOIS %s\r\n" % _nick)
            self.irc_sock.send(bytes(_WHOIS, "UTF-8"))

        if command == 'whowas':
            _nick = data.split()[1]
            _WHOWAS = ("WHOWAS %s\r\n" % _nick)
            self.irc_sock.send(bytes(_WHOWAS, "UTF-8"))

        
After executed, when i type entry box, it doesn't passed string to irc_connection module

I appreciate your help

Btw, I can put copy code from server_channel into irc_connection and that fine. But I can't do Join_channel, Privmsg channel, DCC chat. Because it doesn't connection to socket. Only Server_channel working only.

scotty101
Posts: 2388
Joined: Fri Jun 08, 2012 6:03 pm

Re: tkinter How to pass entry to another module?

Mon Oct 23, 2017 1:41 pm

At the moment the first code listing (server_channel.py??) does not include or call anything in the other program listing but the other program imports server_channel. I'd do this the other way round.

Inside server_channel.py do the following things
import irc_connection
create an instance of the IRC_Server class
open gui.
When the enter button is pressed, call a function which calls a method of the IRC_Server instance passing the value of the entry box as a parameter.

I'll try to create a simple example and post it here.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

scotty101
Posts: 2388
Joined: Fri Jun 08, 2012 6:03 pm

Re: tkinter How to pass entry to another module?

Mon Oct 23, 2017 1:59 pm

Ok a simple dumbed down example so I am not doing all the work for you.

gui.py

Code: Select all

#!/usr/bin/python 3.6
from tkinter import *
from chat_client import ChatClient

def server_get(event):
    text = entry.get()
    client.send_message(text)


client = ChatClient()
client.connect()

root = Tk()
v = StringVar()
text1 = Text(root, height=25, width=125, bg='black', fg='yellow')
scroll = Scrollbar(root, command=text1.yview, orient=VERTICAL)
scroll.config(command=text1.yview)
text1.configure(yscrollcommand=scroll.set)
entry = Entry(root, textvariable = v, bg='white', fg='black')
entry.pack(side = BOTTOM, fill=BOTH)
entry.focus()
text1.pack(side=LEFT, fill=BOTH, expand='YES')
scroll.pack(side=RIGHT, fill=BOTH)
entry.bind('<Return>', server_get)

root.mainloop()
chat_client.py

Code: Select all

class ChatClient:
     def __init__(self):
        print('Created Chat Client')
        
     def connect(self):
        print('Connected')

     def send_message(self, data):
        print("Client sent '{}'".format(data))
The chat_client code has no awareness of the gui code but the gui code creates an instance of my "ChatClient" and is able to send messages to it. It is good design practice to not mix up GUI and 'back-end' functionality, this makes your code more testable and less subject to change if you were to change the layout of the GUI.

PS. I didn't change much of the gui code that you created but if I was doing this, I would make more use of objects and classes to do this.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

supra
Posts: 751
Joined: Thu Feb 28, 2013 9:21 am
Location: Ontario, Canada

Re: tkinter How to pass entry to another module?

Sun Nov 19, 2017 6:53 pm

scotty101 wrote:
Mon Oct 23, 2017 1:59 pm
Ok a simple dumbed down example so I am not doing all the work for you.

gui.py

Code: Select all

#!/usr/bin/python 3.6
from tkinter import *
from chat_client import ChatClient

def server_get(event):
    text = entry.get()
    client.send_message(text)


client = ChatClient()
client.connect()

root = Tk()
v = StringVar()
text1 = Text(root, height=25, width=125, bg='black', fg='yellow')
scroll = Scrollbar(root, command=text1.yview, orient=VERTICAL)
scroll.config(command=text1.yview)
text1.configure(yscrollcommand=scroll.set)
entry = Entry(root, textvariable = v, bg='white', fg='black')
entry.pack(side = BOTTOM, fill=BOTH)
entry.focus()
text1.pack(side=LEFT, fill=BOTH, expand='YES')
scroll.pack(side=RIGHT, fill=BOTH)
entry.bind('<Return>', server_get)

root.mainloop()
chat_client.py

Code: Select all

class ChatClient:
     def __init__(self):
        print('Created Chat Client')
        
     def connect(self):
        print('Connected')

     def send_message(self, data):
        print("Client sent '{}'".format(data))
The chat_client code has no awareness of the gui code but the gui code creates an instance of my "ChatClient" and is able to send messages to it. It is good design practice to not mix up GUI and 'back-end' functionality, this makes your code more testable and less subject to change if you were to change the layout of the GUI.

PS. I didn't change much of the gui code that you created but if I was doing this, I would make more use of objects and classes to do this.
Thank. But I still having one problem.

supra
Posts: 751
Joined: Thu Feb 28, 2013 9:21 am
Location: Ontario, Canada

Re: tkinter How to pass entry to another module?

Thu Nov 23, 2017 1:10 pm

@scotty101. I followed your posedt #3

Code: Select all

from tkinter import *
#import irc_connection2
from irc_connection2 import IRC_Server
 
client = IRC_Server()
client.connect()
And error:

Code: Select all

 from irc_connection2 import IRC_Server
ImportError: cannot import name 'IRC_Server'

scotty101
Posts: 2388
Joined: Fri Jun 08, 2012 6:03 pm

Re: tkinter How to pass entry to another module?

Thu Nov 23, 2017 2:03 pm

Share the contents of irc_connection2.py and I might be able to help.

irc_connection2.py should be in the same folder as the python program trying to import it.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

supra
Posts: 751
Joined: Thu Feb 28, 2013 9:21 am
Location: Ontario, Canada

Re: tkinter How to pass entry to another module?

Thu Nov 23, 2017 2:25 pm

Code: Select all

#!/usr/bin/env python
# This code was written for Python 3.1.1
# version 0.101
 
# Changelog:
# version 0.100
# Basic framework
#
# version 0.101
# Fixed an error if an admin used a command with an argument, that wasn't an admin-only command
 
import socket, sys, threading, time
 
# Hardcoding the root admin - it seems the best way for now
root_admin = "maslen"
 
# Defining a class to run the server. One per connection. This class will do most of our work.
class IRC_Server:
 
    # The default constructor - declaring our global variables
    # channel should be rewritten to be a list, which then loops to connect, per channel.
    # This needs to support an alternate nick.
    def __init__(self, host, port, nick, channel , password =""):
        self.irc_host = host
        self.irc_port = port
        self.irc_nick = nick
        self.irc_channel = channel
        self.irc_sock = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
        self.is_connected = False
        self.should_reconnect = False
        self.command = ""
 
   
    # This is the bit that controls connection to a server & channel.
    # It should be rewritten to allow multiple channels in a single server.
    # This needs to have an "auto identify" as part of its script, or support a custom connect message.
    def connect(self):
        self.should_reconnect = True
        try:
            self.irc_sock.connect ((self.irc_host, self.irc_port))
        except:
            print ("Error: Could not connect to IRC; Host: " + str(self.irc_host) + "Port: " + str(self.irc_port))
            exit(1) # We should make it recconect if it gets an error here
        print ("Connected to: " + str(self.irc_host) + ":" + str(self.irc_port))
       
        str_buff = ("NICK %s \r\n") % (self.irc_nick)
        self.irc_sock.send (str_buff.encode())
        print ("Setting bot nick to " + str(self.irc_nick) )
       
        str_buff = ("USER %s 8 * :X\r\n") % (self.irc_nick)
        self.irc_sock.send (str_buff.encode())
        print ("Setting User")
        # Insert Alternate nick code here.
       
        # Insert Auto-Identify code here.
       
        str_buff = ( "JOIN %s \r\n" ) % (self.irc_channel)
        self.irc_sock.send (str_buff.encode())
        print ("Joining channel " + str(self.irc_channel) )
        self.is_connected = True
        self.listen()
   
    def listen(self):
        while self.is_connected:
            recv = self.irc_sock.recv( 4096 )
            print(recv)
            if str(recv).find ( "PING" ) != -1:
                self.irc_sock.send ( "PONG ".encode() + recv.split() [ 1 ] + "\r\n".encode() )
            if str(recv).find ( "PRIVMSG" ) != -1:
                irc_user_nick = str(recv).split ( '!' ) [ 0 ] . split ( ":")[1]
                irc_user_host = str(recv).split ( '@' ) [ 1 ] . split ( ' ' ) [ 0 ]
                irc_user_message = self.data_to_message(str(recv))
                print ("<" + irc_user_nick + "> " + irc_user_message)
                # "!" Indicated a command
                if ( str(irc_user_message[0]) == "!" ):
                    self.command = str(irc_user_message[1:])
                    #@ (str(recv)).split()[2] ) is simply the channel the command was heard on.
                    self.process_command(irc_user_nick, ( (str(recv)).split()[2] ) )
        if self.should_reconnect:
            self.connect()
   
    def data_to_message(self,data):
        data = data[data.find(':')+1:len(data)]
        data = data[data.find(':')+1:len(data)]
        data = str(data[0:len(data)-5])
        return data
       
    # This function sends a message to a channel, which must start with a #.
    def send_message_to_channel(self,data,channel):
        print ( ( "%s: %s") % (self.irc_nick, data) )
        self.irc_sock.send( (("PRIVMSG %s :%s\r\n") % (channel, data)).encode() )
   
    # This function takes a channel, which must start with a #.
    def join_channel(self,channel):
        if (channel[0] == "#"):
            str_buff = ( "JOIN %s \r\n" ) % (channel)
            self.irc_sock.send (str_buff.encode())
            # This needs to test if the channel is full
            # This needs to modify the list of active channels
           
    # This function takes a channel, which must start with a #.
    def quit_channel(self,channel):
        if (channel[0] == "#"):
            str_buff = ( "PART %s \r\n" ) % (channel)
            self.irc_sock.send (str_buff.encode())
            # This needs to modify the list of active channels
   
       
    # This nice function here runs ALL the commands.
    # For now, we only have 2: root admin, and anyone.
    def process_command(self, user, channel):
        # This line makes sure an actual command was sent, not a plain "!"
        if ( len(self.command.split()) == 0):
            return
        # So the command isn't case sensitive
        command = (self.command).lower()
        # Break the command into pieces, so we can interpret it with arguments
        command = command.split()
        print('command : %s' % command)
       
        # All admin only commands go in here.
        if (user == root_admin):
            # The first set of commands are ones that don't take parameters
            if ( len(command) == 1):
 
                #This command shuts the bot down.    
                if (command[0] == "quit"):
                    str_buff = ( "QUIT %s \r\n" ) % (channel)
                    self.irc_sock.send (str_buff.encode())
                    self.irc_sock.close()
                    self.is_connected = False
                    self.should_reconnect = False
                   
            # These commands take parameters
            else:
               
                # This command makes the bot join a channel
                # This needs to be rewritten in a better way, to catch multiple channels
                if (command[0] == "join"):
                    if ( (command[1])[0] == "#"):
                        irc_channel = command[1]
                        print(irc_channel)
                    else:
                        irc_channel = "#" + command[1]
                    self.join_channel(irc_channel)
                   
                # This command makes the bot part a channel
                # This needs to be rewritten in a better way, to catch multiple channels
                if (command[0] == "part"):
                    if ( (command[1])[0] == "#"):
                        irc_channel = command[1]
                    else:
                        irc_channel = "#" + command[1]
                    self.quit_channel(irc_channel)
 
               
        # All public commands go here
        # The first set of commands are ones that don't take parameters
        if ( len(command) == 1):
       
            if (command[0] == "hi"):
                self.send_message_to_channel( ("Hello to you too, " + user), channel )
            if (command[0] == "moo"):
                self.send_message_to_channel( ("MOO yourself, " + user), channel )
            if (command[0] == "train"):
                self.send_message_to_channel( ("Choo Choo! It's the MysteryTrain!"), channel )
            if (command[0] == "poo"):
                self.send_message_to_channel( ("Don't be a potty mouth"), channel )
            if (command[0] == "readnext"):
                self.send_message_to_channel( ("Visit whatshouldIreadnext.com"), channel )
        else:
            if (command[0] == "bop"):
                self.send_message_to_channel( ("\x01ACTION bopz " + str(command[1]) + "\x01"), channel )
           
 
# Here begins the main programs flow:
 
#test = IRC_Server("CHOOPA.NJ.US.DAL.NET", 6667, "aruna20", "#india")
#test = IRC_Server("irc.malvager.com", 6667, "masbot", "#malvager")
test = IRC_Server("punch.wa.us.dal.net", 6668, "supra", '#india' )
run_test = threading.Thread(None, test.connect)
run_test.start()
 
while (test.should_reconnect):
    time.sleep(5)

supra
Posts: 751
Joined: Thu Feb 28, 2013 9:21 am
Location: Ontario, Canada

Re: tkinter How to pass entry to another module?

Thu Nov 23, 2017 2:27 pm

scotty101 wrote:
Thu Nov 23, 2017 2:03 pm
Share the contents of irc_connection2.py and I might be able to help.

irc_connection2.py should be in the same folder as the python program trying to import it.
Everything in same folder.

scotty101
Posts: 2388
Joined: Fri Jun 08, 2012 6:03 pm

Re: tkinter How to pass entry to another module?

Thu Nov 23, 2017 3:06 pm

If I copy the contents of your irc_connection2.py file and try to import it from another python script, I don't get any errors.
The only way I can replicate the same issue as you is to remove the code from irc_connection2.py.

My suggestion would be to double and triple check that the python file name matches what you have on your "from irc_connection2 import IRC_Server" line.
Also perhaps you have another file with the same name that it is importing instead. To check which file you are importing, try creating a new python script in the same folder with the following code.

Code: Select all

import irc_connection2

print(str(irc_connection2))
print("Done")
For me this reports

Code: Select all

<module 'irc_connection2' from 'C:\\Python34\\Projects\\RaspberryPi\\IRC\\irc_connection2.py'>
Done
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

supra
Posts: 751
Joined: Thu Feb 28, 2013 9:21 am
Location: Ontario, Canada

Re: tkinter How to pass entry to another module?

Thu Nov 23, 2017 4:41 pm

@scotty101.
Thank for your advice. I got it working

Return to “Graphics programming”

Who is online

Users browsing this forum: No registered users and 5 guests