11import sys
22import socket
33import argparse
4- from PyQt6 .QtWidgets import QApplication , QMainWindow , QPushButton , QLabel
5- from PyQt6 .QtCore import QThread , pyqtSignal
4+ from PyQt6 .QtWidgets import (QApplication , QMainWindow , QPushButton , QLabel ,
5+ QGraphicsScene , QGraphicsView , QGraphicsEllipseItem , QGraphicsTextItem , QVBoxLayout , QWidget , QLineEdit )
6+ from PyQt6 .QtCore import Qt , QThread , pyqtSignal
7+ from PyQt6 .QtGui import QBrush , QColor
8+
9+ class NetworkNode (QGraphicsEllipseItem ):
10+ def __init__ (self , x , y , ip , details ):
11+ super ().__init__ (0 , 0 , 50 , 50 )
12+ self .setBrush (QBrush (QColor (0 , 0 , 255 )))
13+ self .setFlag (QGraphicsEllipseItem .GraphicsItemFlag .ItemIsSelectable )
14+ self .setPos (x , y )
15+ self .ip = ip
16+ self .details = details
17+
18+ self .text = QGraphicsTextItem (ip , self )
19+ self .text .setDefaultTextColor (Qt .GlobalColor .white )
20+ self .text .setPos (10 , 10 )
21+
22+ def mousePressEvent (self , event ):
23+ print (f"Clicked on node: { self .ip } \n Details: { self .details } " )
24+ super ().mousePressEvent (event )
625
726class NetworkVisualizerApp (QMainWindow ):
827 def __init__ (self , port ):
928 super ().__init__ ()
1029 self .port = port
1130 self .setWindowTitle ("NetMap - Network Visualizer" )
12- self .setGeometry (100 , 100 , 800 , 600 )
31+ self .setGeometry (100 , 100 , 1000 , 700 )
32+
33+ self .central_widget = QWidget ()
34+ self .setCentralWidget (self .central_widget )
35+ self .layout = QVBoxLayout (self .central_widget )
1336
1437 self .label = QLabel ("Network Map" , self )
15- self .label .move (350 , 50 )
38+ self .layout .addWidget (self .label )
39+
40+ # Graphics View for Network Map
41+ self .scene = QGraphicsScene ()
42+ self .view = QGraphicsView (self .scene )
43+ self .layout .addWidget (self .view )
1644
17- self .btn = QPushButton ("Scan Network" , self )
18- self .btn .move (350 , 100 )
19- self .btn .clicked .connect (self .scan_network )
45+ # Command Input Box
46+ self .command_input = QLineEdit (self )
47+ self .command_input .setPlaceholderText ("Enter command..." )
48+ self .layout .addWidget (self .command_input )
49+ self .command_input .returnPressed .connect (self .send_command )
2050
51+ # Buttons
52+ self .scan_btn = QPushButton ("Scan Network" , self )
53+ self .scan_btn .clicked .connect (self .scan_network )
54+ self .layout .addWidget (self .scan_btn )
55+
56+ # Backend Thread
2157 self .backend_thread = BackendThread (self .port )
22- self .backend_thread .new_data .connect (self .update_label )
58+ self .backend_thread .new_data .connect (self .update_network )
2359 self .backend_thread .start ()
2460
2561 def scan_network (self ):
26- self .backend_thread .send_command ("ping" )
62+ self .backend_thread .send_command ("scan" )
63+
64+ def send_command (self ):
65+ command = self .command_input .text ().strip ()
66+ if command :
67+ self .backend_thread .send_command (command )
68+ self .command_input .clear ()
2769
28- def update_label (self , data ):
29- self .label .setText (f"Server Response: { data } " )
70+ def update_network (self , data ):
71+ self .scene .clear ()
72+ nodes = data .split (";" )
73+ x , y = 50 , 50
74+ for node_info in nodes :
75+ parts = node_info .split ("," )
76+ if len (parts ) >= 2 :
77+ ip , details = parts [0 ], parts [1 ]
78+ node = NetworkNode (x , y , ip , details )
79+ self .scene .addItem (node )
80+ x += 100
81+ if x > 800 :
82+ x = 50
83+ y += 100
3084
3185class BackendThread (QThread ):
3286 new_data = pyqtSignal (str )
@@ -36,15 +90,14 @@ def __init__(self, port):
3690 self .port = port
3791 self .socket = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
3892 self .socket .connect (("localhost" , self .port ))
39- # Send 'True' to indicate that it's a GUI client
4093 self .socket .sendall (b"1\n " )
41-
94+
4295 def run (self ):
4396 while True :
4497 data = self .socket .recv (1024 ).decode ()
4598 if data :
4699 self .new_data .emit (data )
47-
100+
48101 def send_command (self , command ):
49102 self .socket .sendall (command .encode () + b"\n " )
50103
@@ -59,4 +112,4 @@ def run():
59112 sys .exit (app .exec ())
60113
61114if __name__ == "__main__" :
62- run ()
115+ run ()
0 commit comments