Pythonnet Error: XamlParseException : 'Failed to create a 'Click' from the text
Pythonnet Error: XamlParseException : 'Failed to create a 'Click' from the text
我之前在IronPython上工作(用WPF开发一些GUI),最近我开始尝试pythonnet。
但我发现在 IronPython 上工作的 xaml 文件在 CPython + pythonnet 上不工作。在 IronPython 中,我可以在 xaml 文件中定义一个 Button.Click,但在 CPython 中似乎不可能。我试图查找答案,但没有找到任何相关内容。所以希望你能在这里救我...
这是我的主要脚本:
import clr
clr.AddReference(r"wpf\PresentationFramework")
from System.IO import StreamReader
from System.Windows.Markup import XamlReader
from System.Windows import Application, Window
from System.Threading import Thread, ThreadStart, ApartmentState
class MyWindow(Window):
def __init__(self):
stream = StreamReader('test.xaml')
window = XamlReader.Load(stream.BaseStream)
Application().Run(window)
def Button_Click(self, sender, e):
print('Button has clicked')
if __name__ == '__main__':
thread = Thread(ThreadStart(MyWindow))
thread.SetApartmentState(ApartmentState.STA)
thread.Start()
thread.Join()
这里是 test.xmal:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WpfApplication1" Height="300" Width="300">
<Grid>
<Button x:Name="BUTTON" Content="Button" HorizontalAlignment="Left" Margin="101,82,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click" Background="#FFFF1616"/>
</Grid>
</Window>
我得到的错误信息是:
未处理的异常:Python.Runtime.PythonException:XamlParseException:“无法从文本 'Button_Click' 创建 'Click'。”行号“6”和行位置“132”。
奇怪的是,如果我在 IronPython 中加载相同的 xaml 并保持相同的 Class 结构,脚本就可以正常工作:
import wpf
from System.Windows import Application, Window
class MyWindow(Window):
def __init__(self):
self.ui = wpf.LoadComponent(self, 'test.xaml')
def Button_Click(self, sender, e):
print('Button has clicked')
if __name__ == '__main__':
Application().Run(MyWindow())
非常感谢您的帮助!
您不能使用 pythonnet 包在 python 中导入 wpf。但是您可以在 presentationframework 中使用 PresentationFramework 加载 XAML 文件有一些限制。 XamlReader 无法执行事件处理,因此我们可以在 python 文件中手动添加该按钮的事件,而不是在 XAML 文件中。
听到 gui.xaml 代码
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WpfApplication1" Height="300" Width="300">
<Grid>
<Label Content="Hello world" HorizontalAlignment="Left" Height="32" Margin="65,77,0,0" VerticalAlignment="Top" Width="119"/>
<Button Name="button1" Content="Button" HorizontalAlignment="Left" Margin="65,145,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
</Window>
然后听到python密码
import clr
clr.AddReference("wpf\PresentationFramework")
from System.IO import *
from System.Windows.Markup import XamlReader
from System.Windows import *
from System.Threading import Thread, ThreadStart, ApartmentState
from System.Windows.Controls import *
class MyWindow(Window):
def __init__(self):
try:
stream = StreamReader('gui.xaml')
self.window = XamlReader.Load(stream.BaseStream)
ButtoninXAML = LogicalTreeHelper.FindLogicalNode(self.window, "button1")
ButtoninXAML.Click += RoutedEventHandler(self.Button_Click)
Application().Run(self.window)
except Exception as ex:
print(ex)
def Button_Click(self, sender, e):
print('clicked')
if __name__ == '__main__':
thread = Thread(ThreadStart(MyWindow))
thread.SetApartmentState(ApartmentState.STA)
thread.Start()
thread.Join()
我之前在IronPython上工作(用WPF开发一些GUI),最近我开始尝试pythonnet。
但我发现在 IronPython 上工作的 xaml 文件在 CPython + pythonnet 上不工作。在 IronPython 中,我可以在 xaml 文件中定义一个 Button.Click,但在 CPython 中似乎不可能。我试图查找答案,但没有找到任何相关内容。所以希望你能在这里救我...
这是我的主要脚本:
import clr
clr.AddReference(r"wpf\PresentationFramework")
from System.IO import StreamReader
from System.Windows.Markup import XamlReader
from System.Windows import Application, Window
from System.Threading import Thread, ThreadStart, ApartmentState
class MyWindow(Window):
def __init__(self):
stream = StreamReader('test.xaml')
window = XamlReader.Load(stream.BaseStream)
Application().Run(window)
def Button_Click(self, sender, e):
print('Button has clicked')
if __name__ == '__main__':
thread = Thread(ThreadStart(MyWindow))
thread.SetApartmentState(ApartmentState.STA)
thread.Start()
thread.Join()
这里是 test.xmal:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WpfApplication1" Height="300" Width="300">
<Grid>
<Button x:Name="BUTTON" Content="Button" HorizontalAlignment="Left" Margin="101,82,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click" Background="#FFFF1616"/>
</Grid>
</Window>
我得到的错误信息是:
未处理的异常:Python.Runtime.PythonException:XamlParseException:“无法从文本 'Button_Click' 创建 'Click'。”行号“6”和行位置“132”。
奇怪的是,如果我在 IronPython 中加载相同的 xaml 并保持相同的 Class 结构,脚本就可以正常工作:
import wpf
from System.Windows import Application, Window
class MyWindow(Window):
def __init__(self):
self.ui = wpf.LoadComponent(self, 'test.xaml')
def Button_Click(self, sender, e):
print('Button has clicked')
if __name__ == '__main__':
Application().Run(MyWindow())
非常感谢您的帮助!
您不能使用 pythonnet 包在 python 中导入 wpf。但是您可以在 presentationframework 中使用 PresentationFramework 加载 XAML 文件有一些限制。 XamlReader 无法执行事件处理,因此我们可以在 python 文件中手动添加该按钮的事件,而不是在 XAML 文件中。
听到 gui.xaml 代码
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WpfApplication1" Height="300" Width="300">
<Grid>
<Label Content="Hello world" HorizontalAlignment="Left" Height="32" Margin="65,77,0,0" VerticalAlignment="Top" Width="119"/>
<Button Name="button1" Content="Button" HorizontalAlignment="Left" Margin="65,145,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
</Window>
然后听到python密码
import clr
clr.AddReference("wpf\PresentationFramework")
from System.IO import *
from System.Windows.Markup import XamlReader
from System.Windows import *
from System.Threading import Thread, ThreadStart, ApartmentState
from System.Windows.Controls import *
class MyWindow(Window):
def __init__(self):
try:
stream = StreamReader('gui.xaml')
self.window = XamlReader.Load(stream.BaseStream)
ButtoninXAML = LogicalTreeHelper.FindLogicalNode(self.window, "button1")
ButtoninXAML.Click += RoutedEventHandler(self.Button_Click)
Application().Run(self.window)
except Exception as ex:
print(ex)
def Button_Click(self, sender, e):
print('clicked')
if __name__ == '__main__':
thread = Thread(ThreadStart(MyWindow))
thread.SetApartmentState(ApartmentState.STA)
thread.Start()
thread.Join()