tkinter使用xaml编写wpf

引言

在之前的一片文章tkinter使用wpf控件_Smart-Space的博客-CSDN博客中,我们实现了将wpf框架嵌入tkinter中。但是众所周知?,wpf可以通过xaml编写界面,这样能够极大地减少代码编写量,提高效率。

但是,C#的xaml与cs结合是通过编译器实现的,而Python使用 .Net 只能够通过代码实现。不过,曲线救国的方法倒是一大堆。


能够导入xaml的控件

在wpf中,能够导入xaml的有:

  • Window

  • Frame

  • ContentControl及其父类和子类

这些控件,都可以通过设置content属性,确定xaml内容。其中,Frame是通过Navigate方法实现页面跳转。

介于Frame能够切换页面,因此我们选择Frame作为容器控件。


xaml

我们用如下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 1</Run>
    </Paragraph>
    <Paragraph>
      <Run>Paragraph 2</Run>
    </Paragraph>
    <Paragraph>
      <Run>Paragraph 3</Run>
    </Paragraph>
  </FlowDocument>
</RichTextBox>


 </StackPanel>
</Page>

解析xaml

作为 .Net 的一部分,wpf所要求的xaml读取结果当然不是Python自带的xml解析库的返回结果,而是基于System.Windows.MarkupXamlReader的解析结果。

from System.Windows.Markup import XamlReader

page = XamlReader.Parse(xaml)

注意,xaml解析需要在STA线程中执行。

导入Frame

这里直接使用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='''
<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 1</Run>
    </Paragraph>
    <Paragraph>
      <Run>Paragraph 2</Run>
    </Paragraph>
    <Paragraph>
      <Run>Paragraph 3</Run>
    </Paragraph>
  </FlowDocument>
</RichTextBox>


 </StackPanel>
</Page>
'''


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创新🔆

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值