radh-pmac
(Patrick)
February 16, 2025, 10:16am
1
I just wanted to check the current state of pyRevit in relation to using CPython and being able to build UIs.
From my research, it sounds like this wasn’t achievable in the past, and people had to write tools in IronPython and use subprocess to execute cpython code if they needed to connect other libraries to their tooling?
I want to build a simple dialog with a form from a CPython script.
What’s the recommended approach to take, and are there any up to date examples I can refer to?
Thanks!
You can use winforms for simple dialogs.
What doesn’t work is the WPF XAML bindings, and for that the pyrevit.forms is not available for cpython scripts.
A simple Winform example. I had to replicate the Toaster as my IT department burnt the pyRevit Toaster.
__author__ = "Aaron Rumple, AIA"
__copyright__ = "Copyright 2025, Aaron Rumple"
__credits__ = ["Aaron Rumple"]
__license__ = "GPL"
__version__ = "2025.2.07"
__maintainer__ = "Aaron Rumple"
__email__ = "aaronrumple@gmail.com"
__status__ = "Production"
import System
import clr
import sys
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
from System.Windows.Forms import Application, Form, Label, Timer, Button, DockStyle
from System.Drawing import Color, Font, Point, Size, ContentAlignment, FontStyle
class OttoPilotToaster(Form):
def __init__(self, title="Notification", message="You have a new message!"):
# Set form properties
self.FormBorderStyle = 0 # No border
self.StartPosition = 0 # Manual position
self.Size = Size(400, 120)
self.BackColor = Color.Black
self.Opacity = 0.666
self.TopMost = True
self.ShowInTaskbar = False
# Get screen dimensions
screen = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea
self.Location = Point(screen.Width - self.Width - 10, screen.Height - self.Height - 10)
# Create title label
self.title_label = Label()
self.title_label.Text = title
self.title_label.ForeColor = Color.White
self.title_label.Font = Font("Arial", 11, FontStyle.Bold)
self.title_label.BackColor = Color.DarkGray
self.title_label.Size = Size(self.Width, 30)
self.title_label.TextAlign = ContentAlignment.MiddleLeft
self.title_label.Padding = System.Windows.Forms.Padding(10, 0, 0, 0)
self.title_label.Dock = DockStyle.Top
self.title_label.BackColor = Color.Black # Black title bar
self.title_label.Click += self.close_notification # Close on click
self.Controls.Add(self.title_label)
# Create message label
self.message_label = Label()
self.message_label.Text = message
self.message_label.ForeColor = Color.White
self.message_label.Font = Font("Arial", 9, FontStyle.Bold)
self.message_label.TextAlign = ContentAlignment.MiddleLeft
self.message_label.Padding = System.Windows.Forms.Padding(10, 0, 0, 0)
self.message_label.Dock = DockStyle.Fill
self.message_label.Click += self.close_notification # Close on click
self.Controls.Add(self.message_label)
# Timer for auto-close
self.timer = Timer()
self.timer.Interval = 5000 # 15 seconds
self.timer.Tick += self.close_notification
self.timer.Start()
# Close form when clicked anywhere
self.Click += self.close_notification
def close_notification(self, sender, event=None):
self.Close()
def Inflate(ottotitle, ottomessage):
title = sys.argv[1] if len(sys.argv) > 1 else ottotitle
message = sys.argv[2] if len(sys.argv) > 2 else ottomessage
Application.EnableVisualStyles()
Application.Run(OttoPilotToaster(title, message))
if __name__ == "__main__":
Inflate("Otto Pilot says...", "Hello from IronPython!")
2 Likes