1717 get_all_python_venv ,
1818)
1919
20- ALLOWED_FOCUS_EVENTS = [QtCore .QEvent .WindowActivate , QtCore .QEvent .Show ]
20+ ALLOWED_FOCUS_EVENTS = [QtCore .QEvent .Type . WindowActivate , QtCore .QEvent . Type .Show ]
2121LOG = logging .getLogger (__name__ )
2222LOG .setLevel ("DEBUG" )
2323
@@ -147,10 +147,10 @@ def __init__(self, parent=None):
147147 self .setLayout (layout )
148148
149149 # Group 1: Available Virtual Environments
150- available_venv_box = QtWidgets .QGroupBox ("Available virtual environments" )
150+ self . available_venv_box = QtWidgets .QGroupBox ("Available virtual environments" )
151151 available_venv_box_layout = QtWidgets .QVBoxLayout ()
152152 available_venv_box_layout .setContentsMargins (10 , 20 , 10 , 20 )
153- available_venv_box .setLayout (available_venv_box_layout )
153+ self . available_venv_box .setLayout (available_venv_box_layout )
154154
155155 # --> Add text for available virtual environments
156156 available_venv_box_text = QtWidgets .QLabel ()
@@ -164,7 +164,35 @@ def __init__(self, parent=None):
164164 self .venv_table .setSelectionMode (QtWidgets .QTableWidget .SingleSelection )
165165
166166 available_venv_box_layout .addWidget (self .venv_table )
167- layout .addWidget (available_venv_box )
167+ layout .addWidget (self .available_venv_box )
168+
169+ # EXTRA Group: Available Python installation
170+ self .available_python_install_box = QtWidgets .QGroupBox (
171+ "Available base Python versions"
172+ )
173+ available_python_install_box_layout = QtWidgets .QVBoxLayout ()
174+ available_python_install_box_layout .setContentsMargins (10 , 20 , 10 , 20 )
175+ self .available_python_install_box .setLayout (available_python_install_box_layout )
176+
177+ # Python Version, Forge Version Table
178+ self .table = DataTable (installed_python = True , installed_forge = True )
179+ self .table .setSelectionMode (QtWidgets .QTableWidget .SingleSelection )
180+ available_python_install_box_layout .addWidget (self .table )
181+ layout .addWidget (self .available_python_install_box )
182+
183+ # Hide it at first
184+ self .available_python_install_box .hide ()
185+
186+ # EXTRA: Use general Python installations for the above actions
187+ self .check_box_opt = QtWidgets .QCheckBox (
188+ "NOT RECOMMENDED: Use base Python versions instead of virtual environments."
189+ )
190+ self .check_box_opt .setCheckState (QtCore .Qt .CheckState .Unchecked )
191+ layout .addWidget (self .check_box_opt )
192+ self .check_box_opt .stateChanged .connect (self .set_chk_box_focus )
193+ self .check_box_opt .stateChanged .connect (self .display_ctrl )
194+
195+ ####### Launching and package management options #######
168196
169197 # Group 2: Launching Options
170198 launching_options_box = QtWidgets .QGroupBox ("Launching options" )
@@ -234,6 +262,7 @@ def __init__(self, parent=None):
234262
235263 self .package_pip_dict = {
236264 "PyAnsys-Metapackage" : "pyansys" ,
265+ "PyAnsys-Math" : "ansys-math-core" ,
237266 "PyAEDT" : "pyaedt" ,
238267 "PyDPF-Core" : "ansys-dpf-core" ,
239268 "PyDPF-Post" : "ansys-dpf-post" ,
@@ -243,9 +272,12 @@ def __init__(self, parent=None):
243272 "PyFluent-Visualization" : "ansys-fluent-visualization" ,
244273 "PyMAPDL" : "ansys-mapdl-core" ,
245274 "PyMAPDL Reader" : "ansys-mapdl-reader" ,
275+ "PyMechanical" : "ansys-mechanical-core" ,
276+ "PyMotorCAD" : "ansys-motorcad-core" ,
246277 "PyPIM" : "ansys-platform-instancemanagement" ,
247278 "PyPrimeMesh" : "ansys-meshing-prime" ,
248279 "PySeascape" : "ansys-seascape" ,
280+ "PySystem Coupling" : "ansys-systemcoupling-core" ,
249281 "PyTwin" : "pytwin" ,
250282 "Granta MI BoM Analytics" : "ansys-grantami-bomanalytics" ,
251283 "Shared Components" : "ansys-openapi-common" ,
@@ -272,34 +304,6 @@ def __init__(self, parent=None):
272304 hbox_install_pyansys .addWidget (self .button_launch_cmd )
273305 layout .addWidget (pyansys_pkg_manage_box )
274306
275- # EXTRA: Use general Python installations for the above actions
276- self .check_box_opt = QtWidgets .QCheckBox (
277- "NOT RECOMMENDED: Use base Python environments for the above actions."
278- )
279- self .check_box_opt .setCheckState (QtCore .Qt .CheckState .Unchecked )
280- layout .addWidget (self .check_box_opt )
281- self .check_box_opt .stateChanged .connect (self .set_chk_box_focus )
282- self .check_box_opt .stateChanged .connect (self .display_ctrl )
283-
284- # Group 5: Available Python installation
285- self .available_python_install_box = QtWidgets .QGroupBox (
286- "Available Python installations"
287- )
288- self .available_python_install_box_layout = QtWidgets .QVBoxLayout ()
289- self .available_python_install_box_layout .setContentsMargins (10 , 20 , 10 , 20 )
290- self .available_python_install_box .setLayout (
291- self .available_python_install_box_layout
292- )
293-
294- # Python Version, Forge Version Table
295- self .table = DataTable (installed_python = True , installed_forge = True )
296- self .table .setSelectionMode (QtWidgets .QTableWidget .SingleSelection )
297- self .available_python_install_box_layout .addWidget (self .table )
298- layout .addWidget (self .available_python_install_box )
299-
300- self .isHidden = True
301- self .available_python_install_box .hide ()
302-
303307 # ensure the table is always in focus
304308 self .installEventFilter (self )
305309
@@ -310,12 +314,12 @@ def update_table(self):
310314
311315 def display_ctrl (self ):
312316 """Set the focus accordingly depending on check box."""
313- if self .isHidden :
317+ if self .is_chk_box_active () :
314318 self .available_python_install_box .show ()
315- self .isHidden = False
319+ self .available_venv_box . hide ()
316320 else :
317321 self .available_python_install_box .hide ()
318- self .isHidden = True
322+ self .available_venv_box . show ()
319323
320324 def set_chk_box_focus (self , state ):
321325 """Set the focus accordingly depending on check box."""
@@ -381,13 +385,18 @@ def list_packages(self):
381385 self .launch_cmd ("pip list" )
382386
383387 def _update_pck_mnger (self ):
384- """Update package manager if needed."""
385- cmd = ""
386- if "Python" in self .table .active_version :
387- cmd = "python -m pip install -U pip & exit"
388- elif "Conda" in self .table .active_version :
389- cmd = "conda update conda & exit"
390- self .launch_cmd (cmd , True )
388+ """Update package manager if needed.
389+
390+ Notes
391+ -----
392+ Only working on base Python installations, for now.
393+ """
394+ if self .is_chk_box_active ():
395+ if "Python" in self .table .active_version :
396+ cmd = "python -m pip install -U pip && exit"
397+ else : # Otherwise, conda
398+ cmd = "conda update conda --yes && exit"
399+ self .launch_cmd (cmd , minimized_window = True )
391400
392401 def launch_cmd (self , extra = "" , minimized_window = False ):
393402 """Run a command in a new command prompt.
@@ -399,43 +408,91 @@ def launch_cmd(self, extra="", minimized_window=False):
399408 minimized_window : bool, default: False
400409 Whether the window should run minimized or not.
401410 """
411+ min_win = "/w /min" if minimized_window else ""
412+
413+ # is_venv - True : virtual environment , False: base python installation
414+ # is_vanilla_python - True : Vanilla Python , False : Miniforge/Conda
415+
402416 if self .is_chk_box_active ():
417+ is_venv = False
418+ # when base python installation is chosen in the table
403419 py_path = self .table .active_path
420+ py_version = self .table .active_version
421+ # chosen_general_base_is_python = True if "Python" in py_version else False
422+
423+ miniforge_path = "" if "Python" in py_version else py_path
424+ is_vanilla_python = True if miniforge_path == "" else False
404425 else :
426+ is_venv = True
427+ # when virtual environment is chosen in the table
405428 py_path = self .venv_table .active_path
406-
407- min_win = "/w /min" if minimized_window else ""
408- if "Python" in self .table .active_version and self .is_chk_box_active ():
429+ parent_path = os .path .dirname (py_path ) # No Scripts Folder
430+ # If py_path has a folder called conda-meta . then it is a conda environment
431+ is_vanilla_python = (
432+ False if "conda-meta" in os .listdir (parent_path ) else True
433+ )
434+ if is_vanilla_python :
435+ miniforge_path = ""
436+ else :
437+ py_path = os .path .dirname (py_path ) # No Scripts Folder
438+ # If it is a conda environment, then we need to get the path to the miniforge installation
439+ with open (os .path .join (py_path , "conda-meta" , "history" ), "r" ) as f :
440+ for line in f :
441+ if line .startswith ("# cmd:" ):
442+ line = line .lstrip ("# cmd: " )
443+ path = line .strip ().split ("create --prefix" )[0 ]
444+ miniforge_path = (
445+ path .strip ().split ("Scripts" )[0 ].rstrip ("\\ " )
446+ )
447+ break
448+ is_vanilla_python = True if miniforge_path == "" else False
449+
450+ if is_vanilla_python and not is_venv :
409451 scripts_path = os .path .join (py_path , "Scripts" )
410452 new_path = f"{ py_path } ;{ scripts_path } ;%PATH%"
411453
412454 if extra :
413- cmd = f"& { extra } "
455+ cmd = f"&& { extra } "
414456 else :
415- cmd = f"& echo Python set to { py_path } "
457+ cmd = f"&& echo Python set to { py_path } "
416458
417459 subprocess .call (
418- f'start { min_win } cmd /K "set PATH={ new_path } &cd %userprofile%{ cmd } "' ,
460+ f'start { min_win } cmd /K "set PATH={ new_path } && cd %userprofile% { cmd } "' ,
461+ shell = True ,
462+ )
463+ elif is_vanilla_python and is_venv :
464+ # Launch with active python virtual environment
465+ if extra :
466+ cmd = f"&& { extra } "
467+ else :
468+ cmd = f"&& echo Python set to { py_path } "
469+ subprocess .call (
470+ f'start { min_win } cmd /K "{ py_path } \\ activate.bat { py_path } && cd %userprofile% { cmd } "' ,
419471 shell = True ,
420472 )
421- elif not self . is_chk_box_active () :
422- # Launch with active virtual environment
473+ elif not is_vanilla_python and is_venv :
474+ # Launch with active conda virtual environment
423475 if extra :
424- cmd = f"& { extra } "
476+ # Replace the pip install command for conda
477+ extra = extra .replace ("pip" , "conda" )
478+ extra = extra .replace ("conda install" , "conda install --yes" )
479+ cmd = f"&& { extra } "
425480 else :
426- cmd = f"& echo Python set to { py_path } "
481+ cmd = f"&& echo Activating conda forge at path { py_path } "
427482 subprocess .call (
428- f'start { min_win } cmd /K "{ py_path } \\ activate.bat { py_path } & cd %userprofile%{ cmd } "' ,
483+ f'start { min_win } cmd /K "{ miniforge_path } \\ Scripts \\ activate.bat && conda activate { py_path } && cd %userprofile% { cmd } "' ,
429484 shell = True ,
430485 )
431- else : # probably conda
486+ else :
487+ # not is_vanilla_python and not is_venv
432488 if extra :
433489 # Replace the pip install command for conda
434490 extra = extra .replace ("pip" , "conda" )
435- cmd = f"& { extra } "
491+ extra = extra .replace ("conda install" , "conda install --yes" )
492+ cmd = f"&& { extra } "
436493 else :
437- cmd = f"& echo Activating conda forge at path { py_path } "
494+ cmd = f"&& echo Activating conda forge at path { py_path } "
438495 subprocess .call (
439- f'start { min_win } cmd /K "{ py_path } \\ Scripts\\ activate.bat { py_path } & cd %userprofile%{ cmd } "' ,
496+ f'start { min_win } cmd /K "{ miniforge_path } \\ Scripts\\ activate.bat && conda activate { py_path } && cd %userprofile% { cmd } "' ,
440497 shell = True ,
441498 )
0 commit comments