Imagine we’re building a bridge between two islands, but instead of cars, we’re sending files across, and our bridge is made of Python code. We’ll use tkinter
as our toolbox to build a user-friendly control panel. Then, we’ll dive into the world of socket
programming, which is like setting up the telephone lines between our islands, allowing them to talk to each other and send precious cargo (our files) back and forth.
In today’s tutorial, we’re going to create a File Transfer App. You’ll learn how to transfer files in Python, which is ideal for users on the same network, this App facilitates smooth file sharing directly through our Python code.
Let’s get started!
Table of Contents
- Necessary Libraries
- Imports
- FileTransferApp Class
- Instance Variable
- Create Widgets
- Button’s Functions
- Main Block
- Example
- Full Code
Necessary Libraries
Make sure to install the tkinter library via the terminal or your command prompt for the code to function properly:
$ pip install tk
Imports
We begin by importing socket
for device communication, followed by os
for file operations. Then, we import tkinter
to create our graphical user interface (GUI), along with specific classes from tkinter
that will be crucial in our application.
import socket
import os
import tkinter as tk
from tkinter import filedialog, Label, Button, Entry, messagebox
FileTransferApp Class
Next, we lay out a blueprint for our file transfer app, giving the main window a title, setting its dimensions, choosing a background color, and disabling resizing.
class FileTransferApp:
def __init__(self, master):
self.master = master
self.master.title("File Transfer App - The Pycodes")
self.master.geometry("450x560")
self.master.configure(bg="lightblue")
self.master.resizable(False, False)
Instance Variable
self.filename = None # Instance variable for filename
What we did here is create a variable to store and remember the name of the file.
Create Widgets
After that, we create the visuals for our app. This includes the target_ip
label, followed by the ‘IP address’ entry box. We also add three buttons “Select, Send, Receive” File, each triggering a specific function when pressed.
Lastly, the app displays the local IP address.
self.create_widgets()
def create_widgets(self):
# Entry for target IP address
self.ip_entry_label = Label(self.master, text="Target IP:", bg="lightblue", font="arial 12 bold")
self.ip_entry_label.place(x=190, y=100)
self.ip_entry = Entry(self.master, width=40, font="arial 12")
self.ip_entry.place(x=50, y=130)
# Button to select a file
self.select_file_button = Button(self.master, text="Select File", command=self.select_file, font="arial 11")
self.select_file_button.place(x=170, y=190)
# Button to send file
self.send_button = Button(self.master, text="Send File", command=self.send_file, font="arial 11")
self.send_button.place(x=50, y=230)
# Button to receive file
self.receive_button = Button(self.master, text="Receive File", command=self.receive_file, font="arial 11")
self.receive_button.place(x=300, y=230)
# Display local IP address
self.local_ip_label = Label(self.master, text=f"My Local IP is: {socket.gethostbyname(socket.gethostname())}", bg="lightblue", fg="black", font="arial 10 bold")
self.local_ip_label.place(x=50, y=280)
Button’s Functions
Select File
Now we define the functions for the buttons, this one opens a dialog where the user can select and store a file, and if he doesn’t select a file, an error message will appear.
def select_file(self):
self.filename = filedialog.askopenfilename(initialdir=os.getcwd(), title='Select File',
filetypes=(('All files', '*.*'),))
if not self.filename:
messagebox.showerror("ERROR", "No file selected")
Send File
Following that, we create this function to send the selected and stored file to the device, using the local IP address provided by the user. This function also displays a message indicating the success of the process or reports an error if the transfer fails or the target IP address was not entered.
def send_file(self):
target_ip = self.ip_entry.get()
if target_ip and self.filename:
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s, open(self.filename, 'rb') as file:
s.connect((target_ip, 8080))
while file_data := file.read(1024):
s.send(file_data)
messagebox.showinfo("Success", "Data has been transmitted successfully")
except Exception as e:
messagebox.showerror("ERROR", f"Error: {e}")
else:
messagebox.showerror("ERROR", "Please enter a target IP and select a file")
Receive File
Here, we define a function to save the sent file data to a specified directory. It also displays an error message if the file is not received or if the recipient has not selected a directory to receive the sent data.
def receive_file(self):
filename1 = filedialog.asksaveasfilename(initialdir=os.getcwd(), title='Save Received File in',
filetypes=(('All files', '*.*'),))
if filename1:
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('0.0.0.0', 8080))
s.listen(1)
conn, addr = s.accept()
with conn, open(filename1, 'wb') as file:
while file_data := conn.recv(1024):
file.write(file_data)
messagebox.showinfo("Success", "File has been received successfully")
except Exception as e:
messagebox.showerror("ERROR", f"Error: {e}")
else:
messagebox.showerror("ERROR", "Please enter a valid filename")
Main Block
Lastly, this part creates the main window sets up the GUI elements, and starts the program’s main loop (keep it running) until the user chooses not to.
if __name__ == "__main__":
root = tk.Tk()
Label(root, text="Simple File Transfer",bg="lightblue",fg="red",font="arial 20 bold").place(x=50, y=50)
app = FileTransferApp(root)
root.mainloop()
Example
Full Code
import socket
import os
import tkinter as tk
from tkinter import filedialog, Label, Button, Entry, messagebox
class FileTransferApp:
def __init__(self, master):
self.master = master
self.master.title("File Transfer App - The Pycodes")
self.master.geometry("450x560")
self.master.configure(bg="lightblue")
self.master.resizable(False, False)
self.filename = None # Instance variable for filename
self.create_widgets()
def create_widgets(self):
# Entry for target IP address
self.ip_entry_label = Label(self.master, text="Target IP:", bg="lightblue", font="arial 12 bold")
self.ip_entry_label.place(x=190, y=100)
self.ip_entry = Entry(self.master, width=40, font="arial 12")
self.ip_entry.place(x=50, y=130)
# Button to select a file
self.select_file_button = Button(self.master, text="Select File", command=self.select_file, font="arial 11")
self.select_file_button.place(x=170, y=190)
# Button to send file
self.send_button = Button(self.master, text="Send File", command=self.send_file, font="arial 11")
self.send_button.place(x=50, y=230)
# Button to receive file
self.receive_button = Button(self.master, text="Receive File", command=self.receive_file, font="arial 11")
self.receive_button.place(x=300, y=230)
# Display local IP address
self.local_ip_label = Label(self.master, text=f"My Local IP is: {socket.gethostbyname(socket.gethostname())}", bg="lightblue", fg="black", font="arial 10 bold")
self.local_ip_label.place(x=50, y=280)
def select_file(self):
self.filename = filedialog.askopenfilename(initialdir=os.getcwd(), title='Select File',
filetypes=(('All files', '*.*'),))
if not self.filename:
messagebox.showerror("ERROR", "No file selected")
def send_file(self):
target_ip = self.ip_entry.get()
if target_ip and self.filename:
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s, open(self.filename, 'rb') as file:
s.connect((target_ip, 8080))
while file_data := file.read(1024):
s.send(file_data)
messagebox.showinfo("Success", "Data has been transmitted successfully")
except Exception as e:
messagebox.showerror("ERROR", f"Error: {e}")
else:
messagebox.showerror("ERROR", "Please enter a target IP and select a file")
def receive_file(self):
filename1 = filedialog.asksaveasfilename(initialdir=os.getcwd(), title='Save Received File in',
filetypes=(('All files', '*.*'),))
if filename1:
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('0.0.0.0', 8080))
s.listen(1)
conn, addr = s.accept()
with conn, open(filename1, 'wb') as file:
while file_data := conn.recv(1024):
file.write(file_data)
messagebox.showinfo("Success", "File has been received successfully")
except Exception as e:
messagebox.showerror("ERROR", f"Error: {e}")
else:
messagebox.showerror("ERROR", "Please enter a valid filename")
if __name__ == "__main__":
root = tk.Tk()
Label(root, text="Simple File Transfer", bg="lightblue", fg="red", font="arial 20 bold").place(x=80, y=50)
app = FileTransferApp(root)
root.mainloop()
Happy Coding!
Hey would you mind sharing which blog platform you’re using?
I’m looking to start my own blog in the near future but I’m having a difficult
time making a decision between BlogEngine/Wordpress/B2evolution and Drupal.
The reason I ask is because your design and style seems
different then most blogs and I’m looking for something completely unique.
P.S Sorry for getting off-topic but I had to ask!
Oh, absolutely, happy to share! I’m actually on WordPress. I decided to go with a custom theme to give my blog that unique touch you mentioned. Honestly, choosing the right platform can be quite the journey, but WordPress has been super versatile for me. And hey, no worries about the detour – it’s a great question!