1010from typing import Dict , Any , Optional
1111
1212from PySide6 .QtCore import Qt , QTimer , QSettings , QSize , QPoint , Signal
13- from PySide6 .QtGui import QAction , QKeySequence , QFont
13+ from PySide6 .QtGui import QAction , QFont , QPixmap
1414from PySide6 .QtWidgets import (
1515 QApplication , QMainWindow , QWidget , QVBoxLayout , QHBoxLayout ,
16- QMenuBar , QStatusBar , QToolBar , QPushButton , QLabel , QSplitter ,
16+ QStatusBar , QToolBar , QPushButton , QLabel , QSplitter ,
1717 QMessageBox , QFileDialog , QFrame , QSizePolicy
1818)
1919
@@ -47,7 +47,6 @@ def __init__(self):
4747
4848 # Setup UI
4949 self .setup_ui ()
50- self .setup_menus ()
5150 self .setup_toolbar ()
5251 self .setup_statusbar ()
5352 self .setup_connections ()
@@ -102,7 +101,7 @@ def create_control_panel(self):
102101 layout = QVBoxLayout (panel )
103102
104103 # Connection controls - removed duplicate buttons for simplicity
105- # (Connection controls are available in toolbar and menu )
104+ # (Connection controls are available in toolbar)
106105 conn_layout = QHBoxLayout ()
107106 conn_layout .addStretch () # Just add stretch to maintain layout
108107
@@ -127,87 +126,6 @@ def create_control_panel(self):
127126
128127 return panel
129128
130- def setup_menus (self ):
131- """Setup application menus"""
132- menubar = self .menuBar ()
133-
134- # File menu
135- file_menu = menubar .addMenu ("&File" )
136-
137- connect_action = QAction ("&Connect to Camera..." , self )
138- connect_action .setShortcut (QKeySequence .Open )
139- connect_action .setStatusTip ("Connect to an IP camera" )
140- connect_action .triggered .connect (self .show_connection_dialog )
141- file_menu .addAction (connect_action )
142-
143- disconnect_action = QAction ("&Disconnect" , self )
144- disconnect_action .setShortcut (QKeySequence ("Ctrl+D" ))
145- disconnect_action .setStatusTip ("Disconnect from current camera" )
146- disconnect_action .triggered .connect (self .disconnect_camera )
147- file_menu .addAction (disconnect_action )
148- self .disconnect_action = disconnect_action
149-
150- file_menu .addSeparator ()
151-
152- screenshot_action = QAction ("Take &Screenshot" , self )
153- screenshot_action .setShortcut (QKeySequence ("Ctrl+S" ))
154- screenshot_action .setStatusTip ("Save current frame as image" )
155- screenshot_action .triggered .connect (self .take_screenshot )
156- file_menu .addAction (screenshot_action )
157- self .screenshot_action = screenshot_action
158-
159- file_menu .addSeparator ()
160-
161- exit_action = QAction ("E&xit" , self )
162- exit_action .setShortcut (QKeySequence .Quit )
163- exit_action .setStatusTip ("Exit the application" )
164- exit_action .triggered .connect (self .close_application )
165- file_menu .addAction (exit_action )
166-
167- # View menu
168- view_menu = menubar .addMenu ("&View" )
169-
170- fullscreen_action = QAction ("&Fullscreen" , self )
171- fullscreen_action .setShortcut (QKeySequence ("F11" ))
172- fullscreen_action .setStatusTip ("Toggle fullscreen mode" )
173- fullscreen_action .triggered .connect (self .toggle_fullscreen )
174- view_menu .addAction (fullscreen_action )
175-
176- view_menu .addSeparator ()
177-
178- # Video fit mode submenu
179- fit_menu = view_menu .addMenu ("Video &Fit Mode" )
180-
181- fit_actions = []
182- fit_modes = ["Keep Aspect Ratio" , "Keep Aspect Ratio by Expanding" , "Ignore Aspect Ratio" ]
183- for i , mode in enumerate (fit_modes ):
184- action = QAction (mode , self )
185- action .setCheckable (True )
186- action .setData (i )
187- action .triggered .connect (lambda checked , idx = i : self .set_video_fit_mode (idx ))
188- fit_menu .addAction (action )
189- fit_actions .append (action )
190-
191- fit_actions [0 ].setChecked (True ) # Default to first mode
192- self .fit_mode_actions = fit_actions
193-
194- # Tools menu
195- tools_menu = menubar .addMenu ("&Tools" )
196-
197- settings_action = QAction ("&Settings..." , self )
198- settings_action .setShortcut (QKeySequence .Preferences )
199- settings_action .setStatusTip ("Open application settings" )
200- settings_action .triggered .connect (self .show_settings_dialog )
201- tools_menu .addAction (settings_action )
202-
203- # Help menu
204- help_menu = menubar .addMenu ("&Help" )
205-
206- about_action = QAction ("&About..." , self )
207- about_action .setStatusTip ("About this application" )
208- about_action .triggered .connect (self .show_about_dialog )
209- help_menu .addAction (about_action )
210-
211129 def setup_toolbar (self ):
212130 """Setup application toolbar"""
213131 toolbar = QToolBar ("Main Toolbar" )
@@ -249,6 +167,20 @@ def setup_toolbar(self):
249167 fullscreen_action .triggered .connect (self .toggle_fullscreen )
250168 toolbar .addAction (fullscreen_action )
251169
170+ toolbar .addSeparator ()
171+
172+ # Settings button
173+ settings_action = QAction ("Settings" , self )
174+ settings_action .setToolTip ("Open settings" )
175+ settings_action .triggered .connect (self .show_settings_dialog )
176+ toolbar .addAction (settings_action )
177+
178+ # About button
179+ about_action = QAction ("About" , self )
180+ about_action .setToolTip ("About this application" )
181+ about_action .triggered .connect (self .show_about_dialog )
182+ toolbar .addAction (about_action )
183+
252184 def setup_statusbar (self ):
253185 """Setup application status bar"""
254186 self .status_bar = QStatusBar ()
@@ -281,15 +213,21 @@ def setup_connections(self):
281213
282214 def show_connection_dialog (self ):
283215 """Show connection dialog"""
284- dialog = ConnectionDialog (self )
285- dialog .connection_requested .connect (self .connect_to_camera )
286- dialog .exec ()
216+ self . connection_dialog = ConnectionDialog (self )
217+ self . connection_dialog .connection_requested .connect (self .connect_to_camera )
218+ self . connection_dialog .exec ()
287219
288220 def connect_to_camera (self , url : str , name : str ):
289221 """Connect to a camera"""
290222 try :
223+ # Get protocol from the dialog
224+ protocol = "http" # Default fallback
225+ if hasattr (self , 'connection_dialog' ):
226+ protocol = self .connection_dialog .get_stream_protocol ()
227+
291228 self .current_camera_url = url
292229 self .current_camera_name = name
230+ self .current_protocol = protocol
293231
294232 # Apply connection timeout from settings
295233 timeout = self .app_settings .get ('connection_timeout' , 5 ) # Shorter default timeout
@@ -298,10 +236,11 @@ def connect_to_camera(self, url: str, name: str):
298236 # Reset error tracking
299237 self ._last_error_time = 0
300238
301- # Connect to stream
302- self .video_widget .connect_to_stream (url )
239+ # Connect to stream with protocol
240+ self .video_widget .connect_to_stream (url , protocol )
303241
304- self .status_bar .showMessage (f"Connecting to { name } ..." , 3000 )
242+ protocol_display = "RTSP" if protocol == "rtsp" else "HTTP"
243+ self .status_bar .showMessage (f"Connecting to { name } ({ protocol_display } )..." , 3000 )
305244
306245 except Exception as e :
307246 QMessageBox .critical (self , "Connection Error" , f"Failed to connect: { str (e )} " )
@@ -311,6 +250,8 @@ def disconnect_camera(self):
311250 self .video_widget .disconnect_stream ()
312251 self .current_camera_url = ""
313252 self .current_camera_name = ""
253+ self .current_protocol = "http"
254+ self .connection_dialog = None
314255 self .update_ui_state ()
315256
316257 def on_connection_changed (self , connected : bool ):
@@ -343,10 +284,6 @@ def on_error_occurred(self, error_message: str):
343284
344285 def update_ui_state (self ):
345286 """Update UI state based on connection status"""
346- # Update menu actions
347- self .disconnect_action .setEnabled (self .is_connected )
348- self .screenshot_action .setEnabled (self .is_connected )
349-
350287 # Update toolbar actions
351288 self .toolbar_disconnect_action .setEnabled (self .is_connected )
352289 self .toolbar_screenshot_action .setEnabled (self .is_connected )
@@ -413,13 +350,11 @@ def toggle_fullscreen(self):
413350 """Toggle fullscreen mode"""
414351 if self .is_fullscreen :
415352 self .showNormal ()
416- self .menuBar ().show ()
417353 self .statusBar ().show ()
418354 self .findChild (QToolBar ).show ()
419355 self .is_fullscreen = False
420356 else :
421357 self .showFullScreen ()
422- self .menuBar ().hide ()
423358 self .statusBar ().hide ()
424359 self .findChild (QToolBar ).hide ()
425360 self .is_fullscreen = True
@@ -429,10 +364,6 @@ def set_video_fit_mode(self, mode: int):
429364 fit_modes = [Qt .KeepAspectRatio , Qt .KeepAspectRatioByExpanding , Qt .IgnoreAspectRatio ]
430365 if 0 <= mode < len (fit_modes ):
431366 self .video_widget .set_fit_mode (fit_modes [mode ])
432-
433- # Update menu checkmarks
434- for i , action in enumerate (self .fit_mode_actions ):
435- action .setChecked (i == mode )
436367
437368 def show_settings_dialog (self ):
438369 """Show settings dialog"""
0 commit comments