Python CLR WinForms从现有Form打开新窗体报错问题问询
Python CLR开发WinForms多窗体启动报错解决方案
错误原因
InvalidOperationException : Starting a second message loop on a single thread is not a valid operation. Use Form.ShowDialog instead.报错的核心逻辑是WinForms的UI线程同一时间仅允许运行一个消息循环,程序启动时调用的Application.Run(MyForm())已经初始化了全局消息循环,按钮点击事件中再次调用Application.Run()属于非法操作。
解决方案
自定义窗体类调用ShowDialog不生效通常是用法错误或实例被GC回收导致,按照实际需求选择对应方案修改即可:
场景1:弹出模态窗体(弹出后无法操作原窗体,需关闭新窗体后才可操作原窗体)
直接修改按钮点击事件逻辑,替换Application.Run调用为ShowDialog():
def Add_Control_Limits_Form_Click(self, sender, args): # 先实例化自定义的第二个窗体 second_form = MySecondForm() # 模态弹出,不需要额外持有引用也能正常运行 second_form.ShowDialog()
场景2:弹出非模态窗体(两个窗体可同时操作互不阻塞)
使用Show()方法,同时要将新窗体实例存为原窗体的属性,避免局部变量在方法执行完成后被Python GC回收导致窗体闪退:
def Add_Control_Limits_Form_Click(self, sender, args): # 将新窗体实例存为当前窗体的属性,延长生命周期 self.second_form = MySecondForm() # 非模态弹出 self.second_form.Show()
修改后的完整可运行代码
import clr clr.AddReference("System.Windows.Forms") clr.AddReference("System.Drawing") clr.AddReference("System.ComponentModel") from System.Windows.Forms import * from System.Drawing import * class MyForm(Form): def __init__(self): self.StartPosition = FormStartPosition.CenterScreen self.btnTest = Button() self.btnTest.Name = 'btnTest' self.btnTest.Text = "Test" self.btnTest.Size = Size(80, 30) self.Controls.Add(self.btnTest) self.btnTest.Click += self.Add_Control_Limits_Form_Click def Add_Control_Limits_Form_Click(self, sender, args): # 模态弹窗写法二选一 # second_form = MySecondForm() # second_form.ShowDialog() # 非模态弹窗写法二选一 self.second_form = MySecondForm() self.second_form.Show() class MySecondForm(Form): def __init__(self2): self2.StartPosition = FormStartPosition.CenterScreen self2.AutoScaleMode = AutoScaleMode.Font self2.ClientSize = Size(800, 450) self2.Text = "Form2" Application.EnableVisualStyles() Application.SetCompatibleTextRenderingDefault(False) Application.Run(MyForm())
内容的提问来源于stack exchange,提问作者EricALionsFan
相关产品推荐
相关产品推荐

