WinForms on a separate thread IronPython

Hey guys has anyone been able to multi thread a WinForms UI written in Python? I have been able to get it to work but I get deadlocks when trying to call a file dialog. See: python - IronPython running UI on a separate thread and opening a file dialog WinForms - Stack Overflow

Hi Felipe,
What is the benefit of using a separate thread? Your code is running while it waits for the user to select an Excel file?
If not, then I wouldn’t use a separate thread. Calling dialog.ShowDialog() as you already did - would show the ‘select .xlsx file’ form as a modal dialog box, which would prevent the user to do anything else, if that’s what you are looking for:

class SomeForm(System.Windows.Forms.Form):
    def __init__(self):
        button0 = Button()
        button0.Location = System.Drawing.Point(10, 120)
        button0.Click += self.Dialog
        self.Controls.Add(button0)
    
    def Dialog(self, sender, event):
        dialog = OpenFileDialog()
        dialog.Filter = "Excel files (*.xlsx)|*.xlsx"
        if (dialog.ShowDialog() == DialogResult.OK):
            fullpath = dialog.FileName
            MessageBox.Show(fullpath)
            return fullpath
        else:
            return None

form = SomeForm()
form.ShowDialog()

Hi @djordje, I am using a separate thread so that I can keep a responsive viewport while having the WinForms to be open at the same time.

You might consider using a semi-modal dialog instead. In Rhino, a semi-modal dialog is a model dialog that allows for view command and manipulations.

Example:
SampleCsSemiModalFormCommand.cs

– Dale

@felipegutierrezduque, if using this sample, note the difference between Show and ShowDialog, as described here, Show is what you’re looking for I’d say.

The samples provided here are what you want to do. Showing UI on a different thread is extremely rare and not recommended.

What would this look like as IronPython code? I don’t know how to get from any C variant to Python.

class SomeForm(System.Windows.Forms.Form):
    def __init__(self):
        button0 = Button()
        button0.Location = System.Drawing.Point(10, 120)
        button0.Click += self.Dialog
        self.Controls.Add(button0)
        self.TopMost = True  # set it always on top
    
    def Dialog(self, sender, event):
        dialog = OpenFileDialog()
        dialog.Filter = "Excel files (*.xlsx)|*.xlsx"
        if (dialog.ShowDialog() == DialogResult.OK):
            fullpath = dialog.FileName
            MessageBox.Show(fullpath)
            return fullpath
        else:
            return None

form = SomeForm()
#form.ShowDialog()
form.Show()