在之前的一片文章tkinter使用wpf控件_Smart-Space的博客-CSDN博客中,我们实现了将wpf框架嵌入tkinter中。但是众所周知?,wpf可以通过xaml编写界面,这样能够极大地减少代码编写量,提高效率。
但是,C#的xaml与cs结合是通过编译器实现的,而Python使用 .Net 只能够通过代码实现。不过,曲线救国的方法倒是一大堆。
在wpf中,能够导入xaml的有:
Window
Frame
ContentControl及其父类和子类
这些控件,都可以通过设置content属性,确定xaml内容。其中,Frame是通过Navigate方法实现页面跳转。
介于Frame能够切换页面,因此我们选择Frame作为容器控件。
我们用如下xaml作为示例:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1">
<StackPanel Name="LayoutRoot">
<Button Name="btn1"
BorderBrush="Black" BorderThickness="1"
ClickMode="Hover">
ClickMe1
Button>
<Calendar Margin="20"
SelectedDate="2/15/2009"
DisplayDate="3/15/2009"
DisplayDateStart="1/10/2009"
DisplayDateEnd="4/18/2029"/>
<TreeView>
<TreeViewItem Header="Employee1">
<TreeViewItem Header="Jesper"/>
<TreeViewItem Header="Aaberg"/>
<TreeViewItem Header="12345"/>
TreeViewItem>
<TreeViewItem Header="Employee2">
<TreeViewItem Header="Dominik"/>
<TreeViewItem Header="Paiha"/>
<TreeViewItem Header="98765"/>
TreeViewItem>
TreeView>
<RichTextBox Name="richTB">
<FlowDocument>
<Paragraph>
<Run>Paragraph 1Run>
Paragraph>
<Paragraph>
<Run>Paragraph 2Run>
Paragraph>
<Paragraph>
<Run>Paragraph 3Run>
Paragraph>
FlowDocument>
RichTextBox>
StackPanel>
Page>
作为 .Net 的一部分,wpf所要求的xaml读取结果当然不是Python自带的xml解析库的返回结果,而是基于System.Windows.Markup的XamlReader的解析结果。
from System.Windows.Markup import XamlReader
page = XamlReader.Parse(xaml)
注意,xaml解析需要在STA线程中执行。
这里直接使用Frame的Navigate就可以了。
form.Navigate(page)
import clr
clr.AddReference('System.Windows.Forms')
clr.AddReference("PresentationFramework.Classic, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
clr.AddReference("PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
clr.AddReference('WindowsFormsIntegration, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35')#?
clr.AddReference('System.Threading')
from clr import System
from System import Uri
from System.Windows.Markup import XamlReader
from System.Windows import LogicalTreeHelper
from System.Windows.Controls import Frame as wpfFrame,Button as wpfButton
from System.Windows.Forms.Integration import ElementHost
from System.Windows.Forms import Control
from System.Threading import Thread,ApartmentState,ThreadStart
from tkinter import Frame,Tk
from tkinter import ttk
import ctypes
user32=ctypes.windll.user32
from tkwpf import tkWPF
xaml='''
Paragraph 1
Paragraph 2
Paragraph 3
'''
def STAMain():
global media
try:
a=Tk()
a.geometry('500x500')
f=tkWPF(a)
f.pack(fill='both',expand=True)
form=wpfFrame()
page = XamlReader.Parse(xaml)
form.Navigate(page)
f.control(form)
Button1 = LogicalTreeHelper.FindLogicalNode(page, "btn1")
print(Button1)
a.mainloop()
except Exception as err:
print(err)
def main():
t = Thread(ThreadStart(STAMain))
t.ApartmentState = ApartmentState.STA
t.Start()
t.Join()
if __name__ == "__main__":
main()
效果:

因为一些原因,我没有将其写成类,只是做了一个范例而已。有需要的可以自行更改源码。
🔆tkinter创新🔆