Quantcast
Channel: Telerik Blogs
Viewing all articles
Browse latest Browse all 5210

Python Desktop Application Development with Telerik UI for WPF: A Mighty Combo to Try Out

$
0
0

Looking to build GUI for your Python app? Have a Python desktop app which needs some boost and sparkle? Well, guess what? You can now achieve this with the help of our powerful and modern looking UI controls for WPF.

Python and WPF? Oh, yes, IronPython and Telerik UI for WPF are a match made in heaven that will bring your Python desktop application to the next level.

IronPython

Don’t worry if this is the first time you've heard about IronPython. No worries if the first thing that crossed your mind is Iron Man. Yes, I know he had no superpowers per se, yet with the help of his imagination, he did become extremely powerful. Right?

IronPython is a powerful open-source variation of Python, integrated with the .NET Framework. It gives you the ability to use .NET Framework into Python desktop GUI and vice versa. Cool, right? Wanna learn something even cooler—the latest version comes with a built-in template project for Visual Studio 2019.

IronPython project template

So, let’s use it as a base and first create a simple Hello WPF App.

Once the Python project is created, you can see the well-known WPF assemblies are integrated as well as a starting WPF Window and a Python compiled file.

IronPython project files

To me, personally, this looks much like a standard application with the major difference that the code behind C# / VB file is replaced with Python file. If you add a sample button in the XAML window and run the app you will have your first "Hello WPF App in Python" running. Cheers to that!

IronPython Hello World WPF

Bring Telerik Datagrid On

Now let’s make a huge step onto using Telerik controls. First, you need to install the Telerik UI for WPF UI component suite—you can download it from here. Then add the  required Telerik assemblies for using the RadGridView for WPF.

Telerik Assemblies

To reference the binaries in the app, import the clr library and then use the addReference methods:

importwpf
importclr
clr.AddReference('Telerik.Windows.Controls.dll')
clr.AddReference('Telerik.Windows.Controls.Input.dll')
clr.AddReference('Telerik.Windows.Data.dll')
clr.AddReference('Telerik.Windows.Controls.GridView.dll')

As a last step, let’s write some XAML to show a DataGrid populated with ‘very sensitive business information’:

<Window
       Title="WpfApplication1"Height="240"Width="600"x:Name="Root">
    <Grid>
        <telerik:RadGridViewtelerik:StyleManager.Theme="Fluent"
                             ItemsSource="ABCDE"/>
    </Grid>
</Window>

Here we go. The RadGridView (with the awesome Fluent Theme applied) is running in the Python world:

Python5

MVVM Ready

Most of the real-world business apps in WPF use the MVVM pattern to separate the business logic from the View. But how to build the foundation of the MVVM inside our Python WPF project? Let me guide you through.

1. Build a base viewmodel class for all future view models. It should be property-changed ready in order to notify the UI for changes in the data:

fromSystem.ComponentModel importINotifyPropertyChanged, PropertyChangedEventArgs
 
classViewModelBase(INotifyPropertyChanged):
    def__init__(self):
        self.propertyChangedHandlers =[]
 
    defRaisePropertyChanged(self, propertyName):
        args =PropertyChangedEventArgs(propertyName)
        forhandler inself.propertyChangedHandlers:
            handler(self, args)
             
    defadd_PropertyChanged(self, handler):
        self.propertyChangedHandlers.append(handler)
         
    defremove_PropertyChanged(self, handler):
        self.propertyChangedHandlers.remove(handler)   

2. Build a Command class, which will receive actions from UI and will execute them in the ViewModels:

fromSystem.Windows.Input importICommand
 
classCommand(ICommand):
    def__init__(self, execute):
        self.execute =execute
     
    defExecute(self, parameter):
        self.execute()
         
    defadd_CanExecuteChanged(self, handler):
        pass
     
    defremove_CanExecuteChanged(self, handler):
        pass
 
    defCanExecute(self, parameter):
        returnTrue

3. Build the ViewModel classes for the application which will connect the UI to the data:

    3.1. Define a ViewModel class for the data in each DataGrid row:

classClub(ViewModelBase):
    def__init__(self, name, est, capacity, stadName):
        ViewModelBase.__init__(self)
        self.Name =name
        self.Established =est
        self.StadiumCapacity =capacity
        self.StadiumName =stadName

   
    3.2. Define a main ViewModel which provides list of child models and defines commands to manipulate the data:  

fromSystem.Collections.ObjectModel importObservableCollection
fromdatetime importdate
 
classViewModel(ViewModelBase):
    def__init__(self):
        ViewModelBase.__init__(self)
        self.Clubs =ObservableCollection[Club]()
        self.Clubs.Add(Club('FC Barcelona', date(1899, 11, 29), 99354.0, 'Camp Nou'))
        self.Clubs.Add(Club('Juventus F.C.', date(1897, 1, 1), 41507.0, 'Juventus Stadium'))
        self.Clubs.Add(Club('Real Madrid', date(1902, 3, 6), 81044.0, 'Santiago Bernabeu'))
        self.Clubs.Add(Club('Liverpool', date(1892, 1, 1), 54074.0, 'Anfield'))
        self.Clubs.Add(Club('Manchester United', date(1878, 1, 1), 76212.0, 'Old Trafford'))
        self.Clubs.Add(Club('Chelsea', date(1905, 1, 1), 42055.0, 'Stamford Bridge'))
        self.ClearCommand =Command(self.clear)
        self.DecreaseCapacityCommand =Command(self.decreaseCapacity)
     
    defclear(self):
        self.Clubs.Clear()
 
    defdecreaseCapacity(self):
        forclub inself.Clubs :
           cap =club.StadiumCapacity
           club.StadiumCapacity *=0.9
           club.RaisePropertyChanged("StadiumCapacity")

Note that when a property has changed and needs a UI update, the function RaisePropertyChanged is called.

4. Assign the DataContext in code and the ItemsSource & Commands in XAML:

fromSystem.Windows importApplication, Window
 
classMyWindow(Window):
    def__init__(self):
        xaml =wpf.LoadComponent(self, 'WpfApplication1.xaml')
        xaml.Root.DataContext =ViewModel()
 
if__name__ =='__main__':
    Application().Run(MyWindow())
<telerik:RadGridViewShowGroupPanel="False"telerik:StyleManager.Theme="Fluent"
                        ItemsSource="{Binding Clubs}"Height="240"
                        AutoGenerateColumns="False"
                        EditTriggers="None"
                        Margin="30 30 30 50">
    <telerik:RadGridView.Columns>
        <telerik:GridViewDataColumnDataMemberBinding="{Binding Name}"Header="Name"/>
        <telerik:GridViewDataColumnDataMemberBinding="{Binding Established}"Header="Established"/>
        <telerik:GridViewDataColumnDataMemberBinding="{Binding StadiumName}"Header="StadiumName"/>
        <telerik:GridViewDataColumnDataMemberBinding="{Binding StadiumCapacity}"Header="StadiumCapacity"DataFormatString="n2"/>
    </telerik:RadGridView.Columns>
</telerik:RadGridView>
 
<StackPanelOrientation="Horizontal"VerticalAlignment="Bottom"HorizontalAlignment="Center">
    <telerik:RadButtonContent="Clear Clubs"Command="{Binding ClearCommand}"Margin="20"Width="240"
                telerik:StyleManager.Theme="Fluent"/>
    <telerik:RadButtonContent="Decrease Stadium Capacity 10%"Command="{Binding DecreaseCapacityCommand}"Margin="20"Width="240"
                telerik:StyleManager.Theme="Fluent"/>
</StackPanel>

As a result, you get a fully functional MVVM-ready DataGrid with data changes reflected in the UI at run-time:

DataGrid In Python runtime change

Summary

This was a short intro to combining Python desktop GUI and Telerik UI for WPF. I’ll be more than thrilled to learn about your experience with integrating Telerik UI for WPF in your Python projects.

Feel more than welcome to drop us a line in the comments section bellow on how it went with our components or submit your feedback directly to our Feedback Portal.


Viewing all articles
Browse latest Browse all 5210

Trending Articles