import tkinter as tk
from tkinter import messagebox, filedialog
from tkinter import ttk
import socket
import threading
import subprocess
from datetime import datetime
from PIL import Image, ImageTk
import time
# 全局变量
client_socket = None
connected = False
robot_ip = "192.168.1.100" # 假定的机器人IP地址
robot_port = 7930 # 假定的机器人端口
def connect_to_server():
global client_socket, connected
ip = "127.0.0.1"
port = 7930
try:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((ip, port))
connected = True
update_status_indicator('green', f"Connected to server at {ip}:{port}")
log_event(f"Connected to server at {ip}:{port}")
# Start a new thread to receive data
threading.Thread(target=receive_data).start()
except Exception as e:
connected = False
update_status_indicator('red', f"Failed to connect to server: {e}")
log_event(f"Failed to connect to server: {e}")
def disconnect_from_server():
global client_socket, connected
if connected:
client_socket.close()
connected = False
update_status_indicator('red', "Disconnected from server")
log_event("Disconnected from server")
def receive_data():
while connected:
try:
data = client_socket.recv(1024).decode('utf-8')
if not data:
break
current_time = datetime.now().strftime("%H:%M:%S")
received_data_text.insert(tk.END, f"[{current_time}] {data}\n")
received_data_text.yview_moveto(1) # Scroll to the bottom
log_event(f"Received data: {data}")
except Exception as e:
print(f"Error receiving data: {e}")
log_event(f"Error receiving data: {e}")
break
disconnect_from_server()
def launch_application():
app_path = r"D:\aa\Public_Release\aa.exe"
try:
subprocess.Popen(app_path)
log_event("Launched application successfully.")
except Exception as e:
messagebox.showerror("Error", f"Failed to launch application: {e}")
log_event(f"Failed to launch application: {e}")
def log_event(event):
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
log_text.insert(tk.END, f"[{current_time}] {event}\n")
log_text.yview_moveto(1) # Scroll to the bottom
def update_status_indicator(color, message):
status_indicator.config(bg=color)
root.update_idletasks() # Ensure UI updates immediately
messagebox.showinfo("Status", message)
def send_robot_command(command):
if connected and client_socket:
try:
client_socket.sendall(command.encode('utf-8'))
log_event(f"Sent command to Robot: {command}")
except Exception as e:
log_event(f"Failed to send command to Robot: {e}")
def connect_to_robot():
global client_socket, connected
try:
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.settimeout(3) # 设置超时时间为3秒
client_socket.connect((robot_ip, robot_port))
connected = True
update_status_indicator('green', f"Connected to Robot at {robot_ip}:{robot_port}")
log_event(f"Connected to Robot at {robot_ip}:{robot_port}")
# Start a new thread to receive data
threading.Thread(target=receive_data).start()
except socket.timeout:
connected = False
update_status_indicator('red', "Connection timed out.")
log_event("Connection timed out.")
if client_socket:
client_socket.close()
except Exception as e:
connected = False
update_status_indicator('red', f"Failed to connect to Robot: {e}")
log_event(f"Failed to connect to Robot: {e}")
if client_socket:
client_socket.close()
def send_custom_command():
command = custom_command_entry.get()
if command:
send_robot_command(command)
custom_command_entry.delete(0, tk.END) # Clear the entry box after sending
log_event(f"Custom command entered: {command}")
# 创建主窗口
root = tk.Tk()
root.title("TCP Client")
root.geometry("800x600")
# 设置网格权重以确保区域可以正确扩展
root.grid_columnconfigure(0, weight=1)
root.grid_columnconfigure(1, weight=2)
root.grid_columnconfigure(2, weight=1)
root.grid_rowconfigure(0, weight=1) # 上半部分
root.grid_rowconfigure(1, weight=1) # 下半部分
# 上半部分 - 已有内容
left_frame = tk.Frame(root, width=250, height=300)
left_frame.grid(row=0, column=0, padx=5, pady=5, sticky="nsew")
main_label = tk.Label(left_frame, text="Main", font=("Helvetica", 14))
main_label.pack(pady=(10, 5))
image_path = r"C:\Users\Administrator\Desktop\Study\i.png" # 替换为实际图像路径
try:
image = Image.open(image_path)
image = image.resize((150, 150), Image.Resampling.LANCZOS)
img = ImageTk.PhotoImage(image)
except IOError:
img = None
launch_button = tk.Button(left_frame, image=img, command=launch_application)
if img:
launch_button.image = img # Keep a reference!
launch_button.pack(pady=10)
start_label = tk.Label(left_frame, text="Start 2 Visions", font=("Helvetica", 12))
start_label.pack()
middle_frame = tk.Frame(root, width=300, height=300)
middle_frame.grid(row=0, column=1, padx=5, pady=5, sticky="nsew")
control_and_label_frame = tk.Frame(middle_frame)
control_and_label_frame.pack(anchor='center', pady=(10, 0), expand=True)
received_data_label = tk.Label(control_and_label_frame, text="Receive", font=("Helvetica", 14))
received_data_label.pack(side=tk.TOP, anchor='center')
button_width = int(8 * 0.9)
button_height = int(2 * 0.9)
connect_button = tk.Button(control_and_label_frame, text="Connect", command=connect_to_server, width=button_width, height=button_height)
connect_button.pack(side=tk.LEFT, anchor='center', padx=5)
disconnect_button = tk.Button(control_and_label_frame, text="Disconnect", command=disconnect_from_server, width=button_width, height=button_height)
disconnect_button.pack(side=tk.LEFT, anchor='center', padx=5)
spacer_label = tk.Label(control_and_label_frame, text=" ")
spacer_label.pack(side=tk.LEFT, anchor='center')
status_indicator = tk.Frame(control_and_label_frame, width=int(20*0.2), height=int(20*0.2), bg='red')
status_indicator.pack(side=tk.LEFT, anchor='center', padx=(0, 5))
received_data_text = tk.Text(middle_frame, wrap=tk.WORD, height=15, width=40)
received_data_text.pack(padx=10, pady=10)
right_frame = tk.Frame(root, width=200, height=300)
right_frame.grid(row=0, column=2, padx=5, pady=5, sticky="nsew")
log_label = tk.Label(right_frame, text="Log", font=("Helvetica", 14))
log_label.pack(pady=(10, 5))
log_text = tk.Text(right_frame, wrap=tk.WORD, height=15, width=30)
log_text.pack(padx=10, pady=10)
# 下半部分 - Robot 控制区域
bottom_frame = tk.Frame(root, bg='lightgray')
bottom_frame.grid(row=1, column=0, columnspan=3, padx=5, pady=5, sticky="nsew")
# 添加 "Connect 2 Robot" 按钮
connect_robot_button = tk.Button(bottom_frame, text="Connect 2 Robot", command=connect_to_robot)
connect_robot_button.pack(side=tk.TOP, pady=(10, 5))
# U+ 和 U- 按钮所在的框架
control_buttons_frame = tk.Frame(bottom_frame)
control_buttons_frame.pack(side=tk.TOP, pady=10)
u_plus_button = tk.Button(control_buttons_frame, text="U+", command=lambda: send_robot_command("MOV P222"))
u_minus_button = tk.Button(control_buttons_frame, text="U-", command=lambda: print("U- Pressed"))
u_plus_button.pack(side=tk.LEFT, padx=5)
u_minus_button.pack(side=tk.LEFT, padx=5)
# 发送自定义命令的区域
custom_command_frame = tk.Frame(bottom_frame)
custom_command_frame.pack(side=tk.TOP, pady=10, fill=tk.X, expand=True)
custom_command_label = tk.Label(custom_command_frame, text="Enter Command:", font=("Helvetica", 14))
custom_command_label.pack(side=tk.LEFT, padx=5)
custom_command_entry = tk.Entry(custom_command_frame, font=("Helvetica", 20), fg="purple")
custom_command_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)
send_command_button = tk.Button(custom_command_frame, text="Send", command=send_custom_command, font=("Helvetica", 14))
send_command_button.pack(side=tk.LEFT, padx=5)
# 初始化全局变量
client_socket = None
connected = False
# 运行主循环
root.mainloop()