Package: py-imgui-redux
PyImGui-ReduxDearImGui wrapper for python made with PyBind11Read below for adjustments made to the standard APIs.
Otherwise, all documentation from the original libraries remains 100% valid.
Check out the examples folder for some concrete code.InstallInstall the latest version with pippip install py-imgui-reduxModules:imgui-Core DearImGUIimgui.implot-ImPlot libraryimgui.imnodes-ImNodes libraryBackends:imgui.glfw- GLFWAPI AdjustmentsI am writing this library with the primary goal of keeping the original Dear ImGui functional
API as intact as possible. This is because:I want to keep all C++ examples and documentation as relevant as possible since I am lazy and don't want to rewrite everything.I have a love-hate relationship with snake-case.However, there are some minor compromises that have to be made in order to make this happen, primarily in the case of pointers and lists.PointersTake for instance the function:boolDragIntRange2(constchar*label,int*v_current_min,int*v_current_max,/* other args... */);This function returns true if the state changedv_current_minandv_current_maxare pointers to state, and will be read and updated if a change is madeTypical C++ usageintmin=0;intmax=5;// Code ...if(imgui::DragIntRange2("Label",&min,&max)){// Code that happens if a change was made}Python, however, will not let you pass an integer by reference normally, let alone across the C API.
Therefore, the PyImgui-Redux method of accomplishing this:min_val=imgui.IntRef(0)max_val=imgui.IntRef(5)# Code ...ifimgui.DragIntRange2("Label",min_val,max_val):# Code that happens if a change was madepassThese are thin wrappers around a single value.imgui.IntRefimgui.FloatRefimgui.BoolRef# The value can be accessed like somyNum=imgui.IntRef(25)myNum.val+=2ListsTake for instance the functionboolDragInt3(constchar*label,intv[3],/* args ... */);A standard python list is stored sequentially in memory, but the rawvaluesthemselves are wrapped in a python object. Therefore, we cannot easily iterate overjustthe ints/floats, let alone get a pointer to give to ImGui. PyBind11 will happily take a python list and turn it into a vector for us, but in doing so requires making a copy of the list (not ideal for large lists)This is solved in one of two ways.Method 1: PyImgui-Redux Wrappersvals=imgui.IntList([0,5,10])ifimgui.DragInt3("Label",vals):# updating codepassThese are thin wrappers around a C++ vector. They have standard
python list access functions and iteration capabilities.imgui.IntListimgui.FloatListimgui.DoubleListx=imgui.IntList()x.append(25)x.append(36)print(len(x))forvalinx:print(x)x[0]=12See their docs for more information and all functions.Functions that mutate the data, such as vanilla ImGui widgets will
use this method.Method 2: Numpy Arraysimportnumpyasnpxs=np.array([0,5,10])ys=np.array([0,5,10])# Code...implot.PlotScatter("Scatter",xs,ys,len(xs))The implot submodule uses these, as they prevent the need to copy potentially large arrays, and implot functions will not need to change the data as it reads it. Numpy
is also easier to use for data manipulations as is typical with plotting.Thirdly, references to strings are handled similarily to lists (it's actually a subclass of the List wrappers).Take for instance the functionboolInputText(constchar*label,char*buf,size_tbuf_size,/* args ... */);Which takes a pointer to the IO buffer, and also and argument for its size.In Python:myStr=imgui.StrRef("This is a string",maxSize=20)# Code ...ifimgui.InputText("Label",myStr):# code if the text changespassNotice that you don't need to pass the size, this is baked into the StrRef.
Note:maxSizeautomatically takes into account string terminators, i.e.maxSize=20means
your string can hold 20 chars.To change the maxSize:myStr.resize(25)Changing the size lower will drop any extra chars.To get your string back# make a copyx=str(myStr)# orx=myStr.copy()# get a temporary/unsafe pointer# useful for printing large strings without copying# only use said pointer while the object exists# lest ye summon the dreaded seg-faultprint(myStr.view())ImagesLoading images for rendering is simpleimportimguitexture=imgui.LoadTextureFile("myImage.jpg")imgui.Image(texture.texID,imgui.ImVec2(texture.width,texture.height))# ...# Eventuallyglfw.UnloadTexture(texture)# texture can no longer be used without a call to LoadTextureImage file loading is handled viastb_imageand supports various common file formats.
Alternatively, if you wish to do some manual image processing, you can use PILLOW or OpenCV
(or any other image processing library... probably)Important Note:LoadTextureandLoadTextureFilecan only be called after both imgui and glfw have been initialized otherwise openGL will segfaultOpenCV Exampleimportimguiimportcv2image=cv2.imread("myImage.jpg",cv2.IMREAD_UNCHANGED)# cv2.IMREAD_UNCHANGED is important for files with alpha# Have to convert the colors firstimage=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)# If your image has alpha: cv2.COLOR_GBRA2RGBAtexture=imgui.LoadTexture(image.tobytes(),image.shape[1],image.shape[0],image.shape[2])PILLOW ExampleimportimguifromPILimportImageimage=Image.open("myImage.jpg")texture=imgui.LoadTexture(image.tobytes(),image.size[0],image.size[1],len(image.getbands()))Build DependenciesDebian/aptlibx11-dev
libxrandr-dev
libxinerama-dev
libxcursor-dev
libxi-dev
libgl-devFedora/yumlibXrandr-devel
libXinerama-devel
libXcursor-devel
libXi-devel
mesa-libGL-devel