无法将.Net的SaveFileDialog与pythonnet一起使用

Can't use SaveFileDialog of .Net with pythonnet

我在 Python 3.4 中使用 .Net 的 SaveFileDialog class 和 pythonnet 包时遇到了一些问题。在上面您将看到一些代码示例来演示该问题。代码本身工作得很好,直到按钮单击事件被触发并且 SaveFileDialog 应该显示 "dialog.ShowDialog()" 应用程序冻结并且什么也没有发生。用 IronPython 解释器测试了相同的代码,它运行良好。我已经在网上搜索了一些答案,但没有找到与该问题相关的内容

import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
from System.Windows.Forms import Form, Application, Button, SaveFileDialog 
from System.Drawing import Point

class TestForm(Form):
    def __init__(self):
        self.button = Button()
        self.addButton()

    def addButton(self):
        self.button.Location = Point(50,50)
        self.button.Text = "Save s.th"
        self.Controls.Add(self.button)
        self.button.Click += self.buttonClick

    def buttonClick(self, sender, event):
        dialog = SaveFileDialog()
        dialog.FileName = "test one"
        dialog.Title = "Test One"
        print("so far so good")
        dialog.ShowDialog()
        print("Never reaches this point")
Application.Run(TestForm())

您需要设置 STA 线程单元状态,如本期所述:

https://github.com/pythonnet/pythonnet/pull/197

import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
from System.Windows.Forms import Form, Application, Button, SaveFileDialog 
from System.Drawing import Point
from System.Threading import Thread, ThreadStart, ApartmentState

class TestForm(Form):
    def __init__(self):
        self.button = Button()
        self.addButton()

    def addButton(self):
        self.button.Location = Point(50,50)
        self.button.Text = "Save s.th"
        self.Controls.Add(self.button)
        self.button.Click += self.buttonClick

    def buttonClick(self, sender, event):
        dialog = SaveFileDialog()
        dialog.FileName = "test one"
        dialog.Title = "Test One"
        print("so far so good")
        dialog.ShowDialog()
        print("Never reaches this point")


def app_thread():
    app = TestForm()
    Application.Run(app)


def main():
    print('start thread')
    thread = Thread(ThreadStart(app_thread))
    print('set thread apartment STA')
    thread.SetApartmentState(ApartmentState.STA)
    thread.Start()
    thread.Join()


if __name__ == '__main__':
    main()

输出在这里:

start thread
set thread apartment STA
so far so good
Never reaches this point