ModuleNotFoundError: No module named 'PyQt5'

Hi, I am new on Coreform Cubit. I am following the Cardinal tutorial "Converting CSG to CAD Geometry for Multiphysics"https://cardinal.cels.anl.gov/tutorials/csg_to_cad.html which need to use the Coreform Cubit. When I tried to use the DAGMC toolbar mentioned in the tutorial, the terminal shows an error:
********* Now playing /home/mechaos/cubit-dagmc-toolbar-main/scripts/groups_to_block_mats.py **********

Journaled Command: import os

Journaled Command: import sys

Journaled Command:

Journaled Command: filepath = os.path.dirname(os.path.abspath(“file”))

Adding /home/mechaos/cubit-dagmc-toolbar-main/scripts to path
Journaled Command: print(‘Adding ’ + filepath + ’ to path’)

Journaled Command: sys.path.append(filepath)

Journaled Command:

Journaled Command: import cubit

Traceback (most recent call last):
File “”, line 1, in
File “/home/mechaos/cubit-dagmc-toolbar-main/scripts/utils.py”, line 1, in
import PyQt5.QtWidgets as QtWidgets
ModuleNotFoundError: No module named ‘PyQt5’
Current directory is ‘/home/mechaos/Coreform-Cubit-2025.8/bin/’
Journaled Command: cd “/home/mechaos/Coreform-Cubit-2025.8/bin”

It seems that the Cubit doesn’t have PyQt5 installed. I tried to install the module on the terminal but it didn’t work. What should I do to fix that?

Try using an older version of Coreform Cubit for now, prior to 2025.8. The 2025.8 version of Coreform Cubit now uses Qt6 and the latest developers release include PySide6. PySide and PyQt are two different GUI interfaces to the Qt library. PySide is officially support by the Qt Company.

I will look at the dagmc too and update those for PySide6. The changes are pretty simple.

Karl

Hi, Karl. Thanks for your suggestion. I downloaded the old version(2024.08), but somehow, my account can’t pass the old version Cubit activation. I can’t figure out the reason yet.
cubit activation

We modified the licensing for the educational accounts. Let me check on that and get back to you.

Ok, thanks very much.

@Mechaos,

I modified the custom tool bar, and I have attached it here
cubit-dagmc-toolbar-pyside6.tar.gz (108.8 KB)

You will need to download a new version of Coreform Cubit that includes PySide6 in the packaging. Go to Coreform - Coreform Downloads and scroll down to the section that says “Latest Develoment Builds.” Get the most recent version.

. Let me know if you need instructions to install this or if you still have problems.

Karl

Hi, Karl. I downloaded the development version “Coreform-Cubit-2025.11-rc+64249”. There were no problems during installation, while the dagmc toolbar have to make some adjustments about the script path to run. Then I met another error: “AssertionError: SRE module mismatch”

********** Now playing /home/mechaos/cubit-dagmc-toolbar-pyside6/scripts/about_DAGMC.py **********

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/mechaos/Coreform-Cubit-2025.11/bin/python3/lib/python3.10/site-packages/PySide6/__init__.py", line 3, in <module>
    from pathlib import Path
  File "/home/mechaos/anaconda3/envs/moose/lib/python3.13/pathlib/__init__.py", line 8, in <module>
    from ._abc import *
  File "/home/mechaos/anaconda3/envs/moose/lib/python3.13/pathlib/_abc.py", line 15, in <module>
    from glob import _Globber, _no_recurse_symlinks
  File "/home/mechaos/anaconda3/envs/moose/lib/python3.13/glob.py", line 5, in <module>
    import re
  File "/home/mechaos/anaconda3/envs/moose/lib/python3.13/re/__init__.py", line 126, in <module>
    from . import _compiler, _parser
  File "/home/mechaos/anaconda3/envs/moose/lib/python3.13/re/_compiler.py", line 18, in <module>
    assert _sre.MAGIC == MAGIC, "SRE module mismatch"
AssertionError: SRE module mismatch
Current directory is '/home/mechaos/Coreform-Cubit-2025.11/bin/'
Journaled Command: cd "/home/mechaos/Coreform-Cubit-2025.11/bin"

Is this because of the python version mismatch?

Hi, Karl. The problem was solved. I forgot that I had modified the python path on general options. I reset the options to use the default python 3 and problem was gone.

Great. I can now mark this as verified by someone other than me!

Thanks!
Karl

Hi, Karl. Sadly, I met another problem. The tooltip “DAGMC” and “Generate a DAGMC faceting report” are work well, but when I try the “Convert DAGMC Group Assignments to Block Assignments”, I met a name error " ‘Qt’ is not defined ":

********** Now playing /home/mechaos/cubit-dagmc-toolbar-pyside6/scripts/groups_to_block_mats.py **********

Journaled Command: import os

Journaled Command: import sys

Journaled Command: 

Journaled Command: filepath = os.path.dirname(os.path.abspath("__file__"))

Adding /home/mechaos/cubit-dagmc-toolbar-pyside6/scripts to path
Journaled Command: print('Adding ' + filepath + ' to path')

Journaled Command: sys.path.append(filepath)

Journaled Command: 

Journaled Command: import cubit

Journaled Command: from utils import find_claro

Journaled Command: from functools import partial

Journaled Command: 

Journaled Command: from PySide6.QtWidgets import QApplication, QCheckBox, QVBoxLayout, QWidget,\
                              QMessageBox, QFrame, QScrollArea, QPushButton,\
                              QHBoxLayout

Journaled Command: 

Journaled Command: def dagmc_groups():
    """Retrieves groups containing DAGMC metadata

    Returns:
        dict: Dictionary of groups containing DAGMC metadata with
              group id as key and group name as value
    """
    out = {}
    for (name, gid) in cubit.group_names_ids():
        # skip the 'picked' group and other groups
        # that aren't materials
        if name == 'picked' or 'mat' not in name:
            continue
        out[gid] = name

    return out



Journaled Command: def convert_groups_to_blocks(checks):
    """Converts groups containing DAGMC metadata to material assignments
       based on mesh blocks in Cubit

    Args:
        checks : Iterable of Bool values indicating whether the group
                 should be converted to a block or not
    """
    for (checked, (gid, name)) in zip(checks, dagmc_groups().items()):

        if not checked:
            continue

        mat = name.split('/')[0].split(':')[1]

        if not mat:
            print(f'WERID MAT: {mat}')
            continue
        # get all volumes and bodies for this group
        volumes = cubit.get_group_volumes(gid)
        bodies = cubit.get_group_bodies(gid)

        # create a new block
        block_id = cubit.get_next_block_id()
        cmd = f'create block {block_id}'
        cubit.cmd(cmd)
        if len(volumes) != 0:
            vols = " ".join([str(v) for v in volumes])
            cmd = f'block {block_id} add volume {" ".join(volumes)}'
            cubit.cmd(cmd)
        if len(bodies) != 0:
            bods = " ".join([str(b) for b in bodies])
            cmd = f'block {block_id} add body {bods}'
            cubit.cmd(cmd)
        # create a new material with the material identifier for
        # this group
        cmd = f'create material name "{mat}"'
        cubit.cmd(cmd)
        # assign the new material to the mesh group
        cmd = f'block {block_id} material "{mat}"'
        cubit.cmd(cmd)


Journaled Command: def main():

    app = find_claro()

    converter_window = QWidget(parent=app, f=Qt.Window)
    converter_window.setWindowTitle("DAGMC Group to Block Conversion")
    # Set a fixed width to display the full title
    converter_window.resize(400, 300)  # Initial width and height


    # Layout for checkboxes
    checkboxes = []
    converter_layout = QVBoxLayout()

    checkboxLayout = QVBoxLayout()
    # Create checkboxes
    for (gid, name) in dagmc_groups().items():
        checkboxes.append(QCheckBox(f'Group {gid}: {name}'))
        checkboxes[-1].setCheckState(2)
        checkboxLayout.addWidget(checkboxes[-1])

    # Scroll area setup
    scrollArea = QScrollArea()
    scrollWidget = QWidget()
    scrollWidget.setLayout(checkboxLayout)
    scrollArea.setWidget(scrollWidget)
    scrollArea.setWidgetResizable(True)
    scrollArea.resize(400, 200)

    converter_window.setLayout(converter_layout)
    converter_window.show()

    # Create "Select All" and "Deselect All" checkboxes
    selectAllWidget = QPushButton("Select All")
    deselectAllWidget = QPushButton("Deselect All")

    # Set "Select All" and "Deselect All" actions
    selectAllWidget.clicked.connect(lambda _: [c.setCheckState(2) for c in checkboxes])
    deselectAllWidget.clicked.connect(lambda _: [c.setCheckState(0) for c in checkboxes])

    # Add "Select All" and "Deselect All" to a horizontal layout
    selectButtonLayout = QHBoxLayout()
    selectButtonLayout.addWidget(selectAllWidget)
    selectButtonLayout.addWidget(deselectAllWidget)


    # Create a line separator between selection and action buttons
    line = QFrame()
    line.setFrameShape(QFrame.HLine)
    line.setFrameShadow(QFrame.Sunken)

    # Create buttons
    cancelButton = QPushButton("Cancel")
    convertButton = QPushButton("Convert")

    # Set button actions
    close_window = partial(converter_window.close)

    def convert_and_close():
        # create mask and pass to conversion function
        checks = [c.isChecked() for c in checkboxes]
        convert_groups_to_blocks(checks)
        close_window()

    cancelButton.clicked.connect(close_window)
    convertButton.clicked.connect(convert_and_close)
    # Add buttons to a horizontal layout
    buttonLayout = QHBoxLayout()
    buttonLayout.addWidget(cancelButton)
    buttonLayout.addWidget(convertButton)

    # Add button layout to the main layout
    converter_layout.addWidget(scrollArea)
    converter_layout.addLayout(selectButtonLayout)
    converter_layout.addWidget(line)
    converter_layout.addLayout(buttonLayout)

    # ensure the window appears in the center of the screen
    # I don't think this is needed if we set claro as the parent
    # The QWidget will then be centered on Cubit
    #desktop = QApplication.desktop().screenGeometry()
    #desktop = app.window().geometry()
    #window_geometry = converter_window.frameGeometry()
    #window_geometry.moveCenter(desktop.center())
    #converter_window.move(window_geometry.topLeft())



Traceback (most recent call last):
  File "<string>", line 2, in <module>
  File "<string>", line 5, in main
NameError: name 'Qt' is not defined
Current directory is '/home/mechaos/Coreform-Cubit-2025.11/bin/'
Journaled Command: cd "/home/mechaos/Coreform-Cubit-2025.11/bin"

Can you modify the groups_to_blockt_mats.py? Try adding the line
from PySide6.QtCore import Qt
near where the other PySide6 definitions are imported. I’m not quite sure why it would work in on my machine but not yours.

Karl

I added the code line like this:

import os
import sys

filepath = os.path.dirname(os.path.abspath("__file__"))
print('Adding ' + filepath + ' to path')
sys.path.append(filepath)

import cubit
from utils import find_claro
from functools import partial

from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QCheckBox, QVBoxLayout, QWidget,\
                              QMessageBox, QFrame, QScrollArea, QPushButton,\
                              QHBoxLayout

And tried again the tool, another new error occurred :sob:

Traceback (most recent call last):
  File "<string>", line 2, in <module>
  File "<string>", line 19, in main
TypeError: 'PySide6.QtWidgets.QCheckBox.setCheckState' called with wrong argument types:
  PySide6.QtWidgets.QCheckBox.setCheckState(int)
Supported signatures:
  PySide6.QtWidgets.QCheckBox.setCheckState(PySide6.QtCore.Qt.CheckState)
Current directory is '/home/mechaos/Coreform-Cubit-2025.11/bin/'
Journaled Command: cd "/home/mechaos/Coreform-Cubit-2025.11/bin"

I understand why I am not be seeing that error. I did not test with and dagmc groups created. This code at lines 91 to 96 only creates checkboxes if there are dagmc groups.

91 checkboxLayout = QVBoxLayout()
92 # Create checkboxes
93 for (gid, name) in dagmc_groups().items():
94 checkboxes.append(QCheckBox(f’Group {gid}: {name}’))
95 checkboxes[-1].setCheckState(2)
96 checkboxLayout.addWidget(checkboxes[-1])

Instead of setCheckState(2) at line 95 in the new syntax that should be setCheckState(Qt.Checked). Lines 114 and 115 also need to be updated. The 2 should be changed to Qt.Checked and the 0 goes to Qt.Unchecked.

Thanks for helping me debug this. I will run a full case in the morning.

Karl