Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

im_file_dialog will not work when using a pure python backend, or when using HelloImGui::Run (use portable-file-dialogs instead) #294

Open
bgribble opened this issue Dec 11, 2024 · 3 comments
Labels
faq A frequent issue, remaining opened to facilitate discoverability

Comments

@bgribble
Copy link

Hi, I am attempting to add im_file_dialog to my app but I am running in to an error when following the example code in demo_widgets.py. Once I have actually created the dialog, the next call to lfd.FileDialog.instance().is_done() errors out with a bad_function_call exception.

I am using an imgui_bundle wheel downloaded from the Github CI dated Dec 5 with Python 3.12.8 on Linux.

Here's some code to reproduce.

from imgui_bundle import imgui
from imgui_bundle.python_backends.sdl_backend import SDL2Renderer
from imgui_bundle import im_file_dialog as ifd

import OpenGL.GL as gl  # type: ignore
from sdl2 import *  # type: ignore
import ctypes
import sys


class AppState:
    text: str = """Hello, World\nLorem ipsum, etc.\netc."""
    text2: str = "Ahh"


app_state = AppState()


def main():
    window, gl_context = impl_pysdl2_init()
    imgui.create_context()
    impl = SDL2Renderer(window)

    running = True
    event = SDL_Event()
    while running:
        while SDL_PollEvent(ctypes.byref(event)) != 0:
            if event.type == SDL_QUIT:
                running = False
                break
            impl.process_event(event)
        impl.process_inputs()

        imgui.new_frame()

        imgui.begin("File selector problem", True)
        imgui.text("Button should open file selector dialog.")
        imgui.text("On my system, throws 'bad_function_call'")
        imgui.text("Code taken from demo_widgets.py")

        if imgui.button("File..."):
            ifd.FileDialog.instance().open(
                "##choose_file",
                "Select a file",
                "",
            )

        if ifd.FileDialog.instance().is_done("##choose_file"):
            if ifd.FileDialog.instance().has_result():
                result = ifd.FileDialog.instance().get_results()
                if result:
                    filename = result[0].path()
                    print(f"[file dialog] got path {filename} for result {result}")
            ifd.FileDialog.instance().close()


        imgui.end()

        gl.glClearColor(1.0, 1.0, 1.0, 1)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)

        imgui.render()
        impl.render(imgui.get_draw_data())
        SDL_GL_SwapWindow(window)

    impl.shutdown()
    SDL_GL_DeleteContext(gl_context)
    SDL_DestroyWindow(window)
    SDL_Quit()


def impl_pysdl2_init():
    width, height = 1280, 720
    window_name = "minimal ImGui/SDL2 example"

    if SDL_Init(SDL_INIT_EVERYTHING) < 0:
        print(
            "Error: SDL could not initialize! SDL Error: "
            + SDL_GetError().decode("utf-8")
        )
        sys.exit(1)

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1)
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24)
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8)
    SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1)
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1)
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8)
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG)
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4)
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1)
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE)

    SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, b"1")
    SDL_SetHint(SDL_HINT_VIDEO_HIGHDPI_DISABLED, b"1")
    SDL_SetHint(SDL_HINT_VIDEODRIVER, b"wayland,x11")
    SDL_SetHint(SDL_HINT_VIDEO_X11_FORCE_EGL, b"1")

    window = SDL_CreateWindow(
        window_name.encode("utf-8"),
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        width,
        height,
        SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE,
    )

    if window is None:
        print(
            "Error: Window could not be created! SDL Error: "
            + SDL_GetError().decode("utf-8")
        )
        sys.exit(1)

    gl_context = SDL_GL_CreateContext(window)
    if gl_context is None:
        print(
            "Error: Cannot create OpenGL Context! SDL Error: "
            + SDL_GetError().decode("utf-8")
        )
        sys.exit(1)

    SDL_GL_MakeCurrent(window, gl_context)
    if SDL_GL_SetSwapInterval(1) < 0:
        print(
            "Warning: Unable to set VSync! SDL Error: " + SDL_GetError().decode("utf-8")
        )
        sys.exit(1)

    return window, gl_context


if __name__ == "__main__":
    main()
@pthom
Copy link
Owner

pthom commented Dec 11, 2024

Hi,
I'll study this. In the meantime I really suggest you to use portable_file_dialogs: it is better in every way:

  • native dialogs
  • support high dPI
  • also offers notifications

@bgribble
Copy link
Author

In the meantime I really suggest you to use portable_file_dialogs: it is better in every way:

ok, I had already done this as a placeholder, good to know it's a better solution and doesn't need replacing!

@pthom pthom closed this as completed Dec 12, 2024
@pthom pthom changed the title im_file_dialog throws bad_function_call when opened ImFileDialog will not work when using a pure python backend Dec 13, 2024
@pthom pthom changed the title ImFileDialog will not work when using a pure python backend im_file_dialog will not work when using a pure python backend Dec 13, 2024
@pthom pthom changed the title im_file_dialog will not work when using a pure python backend im_file_dialog will not work when using a pure python backend, or when using HelloImGui::Run Dec 13, 2024
@pthom
Copy link
Owner

pthom commented Dec 13, 2024

The reason for the failure is:

The user of ImFileDialog (or im_file_dialog in Python) needs to provide an implementation for a function "CreateTexture" that transfers pixel data to the GPU.

ImmApp:Run() does this for you. However, when using HelloImGui::Run() or when using a pure python backend, this is not done.

Solution: use portable-file-dialogs instead

@pthom pthom changed the title im_file_dialog will not work when using a pure python backend, or when using HelloImGui::Run im_file_dialog will not work when using a pure python backend, or when using HelloImGui::Run (use portable-file-dialogs instead) Dec 13, 2024
@pthom pthom reopened this Dec 13, 2024
@pthom pthom added the faq A frequent issue, remaining opened to facilitate discoverability label Dec 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
faq A frequent issue, remaining opened to facilitate discoverability
Projects
None yet
Development

No branches or pull requests

2 participants