How can I make a simple input form for my Python script?
-
Hello,
I'm new about Python and Cinema 4D scripting. I've done many part of my script but I could not achieve to make a simple form that will get- 3 string values
- 2 check box values.
- a directory path (I need to get a target folder path)
could anyone help me about making this form please?
thank you
-
... while the Team probalby will ask you to provide more context / detail ... have you looked at the sdk examples ?
kind regards
-
Hello @delizade,
thank you for reaching out to us. I am a bit confused when you say:
I'm new about Python and Cinema 4D scripting.
You have more than 20 postings in your account, asking Python questions which I would hardly classify as being new? Nonetheless, windows or 'input forms' are called dialogs in Cinema 4D and represented by the type
c4d.gui.GeDialog
. There is also another form of GUI definitions called descriptions, but they are tied to classic API nodes, e.g., a Cube object or a Noise shader. Dialogs can be modal and non-modal. In a 'Script [Manager script]' you are bound to modal dialogs, i.e., the user can only interact with the dialog until the dialog has been closed.We also have a series of GeDialog related example scripts on GitHub. I also provided a small example which probably does some things you want to do.
Cheers,
FerdinandThe result:
The code:
"""Simple example for a custom dialog in Cinema 4D. The example will contain a file selection element and a button, as well as a multiline text box. Pressing the button will load the content of a selected file into the text box. Windows are represented by the class c4d.gui.GeDialog in Cinema 4D. There are two ways to define dialogs, programmatically, as shown here, or with the help of something which is called a resource file. Resource files work similarly to other GUI markups, as for example XAML for C# or QT-XML for QT. The dialog raised here is modal, i.e., the user must focus on the dialog. For async, i.e., non-modal dialogs you must write a plugin and cannot use a script (there are ways to wiggle around that restriction, but it is not recommended to do that.) For more information, see the Python and C++ documentation of Cinema 4D on dialogs and dialog ressources. """ import c4d import os class MyDialog(c4d.gui.GeDialog): """Defines a dialog. """ ID_TEXT = 1000 ID_CHECKBOX = 1001 ID_FILENAME = 1002 ID_MULTILINE = 1003 ID_BUTTON = 1004 ID_GROUP = 10000 def CreateLayout(self) -> bool: """Called by Cinema 4D to populate the dialog with gadgets. """ # Set the title of the dialog. self.SetTitle("My Dialog") # Open a container to put other elements into. self.GroupBegin(id=MyDialog.ID_GROUP, flags=c4d.BFH_SCALEFIT, cols=1) self.GroupSpace(spacex=5, spacey=5) # Add a text box and a check box. self.AddEditText(id=MyDialog.ID_TEXT, flags=c4d.BFH_SCALEFIT) self.AddCheckbox(id=MyDialog.ID_CHECKBOX, flags=c4d.BFH_SCALEFIT, initw=0, inith=0, name="Check") # A Filename, i.e., an interface to select a file is a bit more fringe and must be added # over its custom GUI. self.AddCustomGui(id=MyDialog.ID_FILENAME, pluginid=c4d.CUSTOMGUI_FILENAME, name="Path", flags=c4d.BFH_SCALEFIT, minw=0, minh=0, customdata=c4d.BaseContainer()) # Add text box spanning multiple lines (that is set to read only mode). self.AddMultiLineEditText(id=MyDialog.ID_MULTILINE, flags=c4d.BFH_SCALEFIT, inith=50, style=c4d.DR_MULTILINE_READONLY) # Add a button. self.AddButton(id=MyDialog.ID_BUTTON, flags=c4d.BFH_SCALEFIT, name="Run") # Close the lyaout group. self.GroupEnd() return super().CreateLayout() def InitValues(self) -> bool: """Called by Cinema 4D to initialize a layout. """ self.SetString(MyDialog.ID_TEXT, "Hello World!") self.SetBool(MyDialog.ID_CHECKBOX, True) self.SetFilename(MyDialog.ID_FILENAME, "") self.SetString(MyDialog.ID_MULTILINE, "") return super().InitValues() @staticmethod def ReadFile(filename: str) -> str: """Custom static function to read the content of a file into a string. """ if not os.path.exists(filename): raise OSError("Could not access file.") try: with open(filename, mode="rt") as f: return f.read() except Exception as e: raise OSError(f"Could not read access file {filename}.") def Command(self, mid: int, msg: c4d.BaseContainer) -> bool: """Called by Cinema 4D when the user interacts with one of the gadgets in the dialog. """ # The "Run" button has been pressed. if mid == MyDialog.ID_BUTTON: # Read the content of the file if it has been selected and put it into the multiline # text box, otherwise open an error dialog. filename = self.GetFilename(MyDialog.ID_FILENAME) if filename: self.SetString(MyDialog.ID_MULTILINE, MyDialog.ReadFile(filename)) else: c4d.gui.MessageDialog("Please select a file first.") return super().Command(mid, msg) def main(): """Opens the dialog. """ # Instantiate the dialog. dialog = MyDialog() # Open the dialog in modal mode, i.e., it will be the only thing the user can focus on. dialog.Open(dlgtype=c4d.DLG_TYPE_MODAL_RESIZEABLE, defaultw=400, xpos=-2, ypos=-2) if __name__=='__main__': main()