Objects and Collection Visibility Checker issue

I’m making a script to let me know when objects are visible but not rendered and vice versa. I don’t know how to code, so this is 100% ChatGPT, but it almost works perfectly.

So, we can’t figure out is how to check the Collection visibility and render state: here if a collection is hidden, the script will tell you about all the objects in the collection instead of just telling you “Collection X is hidden but rendered”, what would be the correct function to call in order to fix that?

bl_info = {
    "name": "Render Checker",
    "author": "AX50 & ChatGPT",
    "version": (1, 0, 0),
    "blender": (3, 0, 0),
    "description": "Displays conflicts between viewport visibility and render visibility for objects.",
    "category": "Object",
}

import bpy

class OBJECT_PT_non_rendered_highlight(bpy.types.Panel):
    """Panel to list objects with render/viewport conflicts"""
    bl_label = "Render/Viewport Conflicts"
    bl_idname = "OBJECT_PT_non_rendered_highlight"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Tool'

    def draw(self, context):
        layout = self.layout
        
        # Section 1: Objects visible in Viewport but not Rendered
        layout.label(text="Viewport Visible, Not Rendered:", icon='ERROR')
        for obj in bpy.data.objects:
            # Skip cameras
            if obj.type == 'CAMERA':
                continue
            
            # Ignore objects hidden in both viewport and render
            if obj.hide_viewport and obj.hide_render:
                continue
            
            # Check if visible in viewport but not rendered
            if obj.visible_get() and obj.hide_render:
                row = layout.row()
                row.label(text=obj.name, icon='OUTLINER_OB_MESH')
        
        # Section 2: Objects Rendered but Not Visible in Viewport
        layout.separator()  # Add a divider
        layout.label(text="Rendered, Not Viewport Visible:", icon='INFO')
        for obj in bpy.data.objects:
            # Skip cameras
            if obj.type == 'CAMERA':
                continue
            
            # Ignore objects hidden in both viewport and render
            if obj.hide_viewport and obj.hide_render:
                continue
            
            # Check if rendered but not visible in viewport
            if not obj.hide_render and not obj.visible_get():
                row = layout.row()
                row.label(text=obj.name, icon='OUTLINER_OB_MESH')

def register():
    bpy.utils.register_class(OBJECT_PT_non_rendered_highlight)

def unregister():
    bpy.utils.unregister_class(OBJECT_PT_non_rendered_highlight)

if __name__ == "__main__":
    register()

If you ant to test it, the script makes a new panel in the Tool section and lets you know when there are conflicts

You can essentially repeat the same code, but with the word collection instead of object, the render and visibility properties have the same name:

for collection in bpy.data.collections:
    if collection.hide_viewport and collection.hide_render
        continue
    if not collection.hide_render and not collection.hide_viewport:
        row = layout.row()
        row.label(text=collection.name, icon='OUTLINER_COLLECTION')

Thanks! It’s going in the right direction thanks to your input, but there’s a few things I don’t know how to change:

-For now the script checks the visibility status via the Screen button (Disable in Viewport) of the Outliner, is it possible to make so the Eye button (Hide in Viewport) does the same?

-When there’s a conflict for a Collection, the script also lists all the objects of that collection in the Objects section, is there a way for the script to ignore the objects in that case?

bl_info = {
    "name": "Render Checker",
    "author": "Blender Artists community",
    "version": (1, 0, 0),
    "blender": (3, 0, 0),
    "description": "Displays conflicts between viewport visibility and render visibility for objects.",
    "category": "Object",
}

import bpy

class OBJECT_PT_non_rendered_highlight(bpy.types.Panel):
    """Panel to list objects with render/viewport conflicts"""
    bl_label = "Render/Viewport Conflicts"
    bl_idname = "OBJECT_PT_non_rendered_highlight"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = 'Tool'

    def draw(self, context):
        layout = self.layout
        
        # Section 1: Objects visible in Viewport but not Rendered
        layout.label(text="Viewport Visible, Not Rendered:", icon='ERROR')
        for obj in bpy.data.objects:
            # Skip cameras
            if obj.type == 'CAMERA':
                continue
            
            # Ignore objects hidden in both viewport and render
            if obj.hide_viewport and obj.hide_render:
                continue
            
            # Check if visible in viewport but not rendered
            if obj.visible_get() and obj.hide_render:
                row = layout.row()
                row.label(text=obj.name, icon='OUTLINER_OB_MESH')
        
        # Section 2: Objects Rendered but Not Visible in Viewport
        layout.separator()  # Add a divider
        layout.label(text="Rendered, Not Viewport Visible:", icon='INFO')
        for obj in bpy.data.objects:
            # Skip cameras
            if obj.type == 'CAMERA':
                continue
            
            # Ignore objects hidden in both viewport and render
            if obj.hide_viewport and obj.hide_render:
                continue
            
            # Check if rendered but not visible in viewport
            if not obj.hide_render and not obj.visible_get():
                row = layout.row()
                row.label(text=obj.name, icon='OUTLINER_OB_MESH')

         # Section 3: Collections Visible but Not Rendered
        layout.separator()  # Add a divider
        layout.label(text="Collection Visible, Not Rendered:", icon='ERROR')
        for collection in bpy.data.collections:
            
            # Ignore Collection hidden in both viewport and render
            if collection.hide_viewport and collection.hide_render:
                continue
            
             # Check if visible in viewport but not rendered
            if collection.hide_render and not collection.hide_viewport:
                row = layout.row()
                row.label(text=collection.name, icon='OUTLINER_COLLECTION')

         # Section 4: Collections Rendered but Not Visible in Viewport
        layout.separator()  # Add a divider
        layout.label(text="Collection Rendered, Not Viewport Visible:", icon='INFO')
        for collection in bpy.data.collections:
           
           # Ignore Collections hidden in both viewport and render
            if collection.hide_viewport and collection.hide_render:
                continue
            
            # Check if rendered but not visible in viewport
            if not collection.hide_render and collection.hide_viewport:
                row = layout.row()
                row.label(text=collection.name, icon='OUTLINER_COLLECTION')
                
                

def register():
    bpy.utils.register_class(OBJECT_PT_non_rendered_highlight)

def unregister():
    bpy.utils.unregister_class(OBJECT_PT_non_rendered_highlight)

if __name__ == "__main__":
    register()

It looks like the camera and screen are both variables, but the eye is a function:
obj.hide_get()