Win forms - clicking the X sends information!

I have a winform.
If I click button1 it sends my form information (I want this) :slight_smile:
If I click button2 it sends, “RESET” (I want this) :slight_smile:

However, if I click the ‘X’ in the top right of the window it sends the last item in my list. (I do not want this) :frowning:

I’ve tried a variety of ways to get it to stop but I’m stuck.

	def ButtonClicked(self, sender, args):
		self.value = "THIS TEXT NEVER STICKS"
		if sender == self.button2:  # Cancel
			self.value = "RESET"
		elif sender == self.button1:  # Output my list
			checked_values = []  # Create a list to store checked tick box values
			for tick_box in self.tick_boxes:
				if tick_box.Checked:
					checked_values.append(tick_box.Tag)  # Store the value associated with the checked tick box
			self.value = checked_values  # Output the list of checked values
		elif args.CloseReason == CloseReason.UserClosing:
			self.value = "argh this does not work either"
		self.Close()

I’ve also tried some ‘on form closing’ conditions but they seem to mess up my button1 output.

Hi @Alien ,

Are you using tkinter to create this form? If so, perhaps the following approach might work for you:
PS: I made this in PyCharm so you probably have to change and remove some stuff to work inside a Dynamo Python node.

import tkinter as tk
from tkinter import messagebox

class MyForm:
    def __init__(self, root):
        self.root = root
        root.title("Tkinter Example")

        self.value = None

        self.button1 = tk.Button(root, text="Button 1", command=self.button1_clicked)
        self.button1.pack()

        self.button2 = tk.Button(root, text="Button 2", command=self.button2_clicked)
        self.button2.pack()

        self.root.protocol("WM_DELETE_WINDOW", self.on_close)

    def button1_clicked(self):
        checked_values = [] 
        self.value = checked_values
        self.root.destroy()

    def button2_clicked(self):
        self.value = "RESET"
        self.root.destroy()

    def on_close(self):
        self.value = "The window was closed using 'X' button"
        self.root.destroy()

if __name__ == "__main__":
    root = tk.Tk()
    form = MyForm(root)
    root.mainloop()

    result = form.value
    print("Result:", result) #Or use OUT = here
1 Like

I am not using tkinter .

Can’t work out how to get it in Revit 21.

Could you share the full code you’re using regarding the winform?

import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
import System
from System.Windows.Forms import *
from System.Drawing import *
import os
from System.Diagnostics import Process

ViewTemplateKeys = IN[0][0] #These are sheet names
RevitSheets = IN[0][1] # These are Revit sheets

class CreateWindow(Form):
	def __init__(self):
			self.Name = "Create Window"
			self.Text = ""
			self.CenterToScreen()
			self.value = None
						
			self.groupBox = GroupBox()
			self.groupBox.Parent = self
			self.groupBox.Location = Point(10, 10)
			self.groupBox.Text = "Select all sheets to be copied"
			self.groupBox.Font = Font("Arial", 10, FontStyle.Bold)
			
			# Create a list to store radio buttons
			self.tick_boxes = []
	
			y = 50
			x = 0
			for i, key in enumerate(ViewTemplateKeys):
				tick_box = CheckBox()
				tick_box.Parent = self.groupBox
				tick_box.Location = Point(10, y)
				tick_box.AutoSize = True
				tick_box.Text = key
				tick_box.Font = Font("Arial", 10)
				tick_box.CheckedChanged += self.radioButton_CheckedChanged
				tick_box.Tag = RevitSheets[i]  # Store the associated key
				tick_box.Checked = True  # Check the tick box initially
				self.tick_boxes.append(tick_box)
				y += 30
			self.groupBox.Size = Size(y + 150, y +15)
			
			self.button1 = Button()
			self.button1.Parent = self
			self.button1.Text = "Pick View Template"
			self.button1.Font = Font("Arial", 10)
			self.button1.Location = Point(x +120, y +115)
			self.button1.Width = 150
			self.button1.Height = 30
			self.button1.Click += self.ButtonClicked
			self.button1.BackColor = Color.DarkSlateBlue
			self.button1.ForeColor = Color.White
			
			self.button2 = Button()
			self.button2.Parent = self
			self.button2.Text = "Cancel"
			self.button2.Font = Font("Arial", 10)
			self.button2.Location = Point(20, y +115)
			self.button2.Width = 90
			self.button2.Height = 30
			self.button2.Click += self.ButtonClicked
			self.button2.BackColor = Color.Red
			self.button2.ForeColor = Color.White
					
			# Make the form always on top + set the size
			self.TopMost = True
			self.Size = Size(x + 320, y + 220)
		
	def radio_button_toggled(self):
		sender = self.sender()  # Get the sender
		if sender.isChecked():
			# Uncheck all other radio buttons in the list
			for radio_button in self.tick_boxes:
				if radio_button != sender:
					radio_button.setChecked(False)
		
	def radioButton_CheckedChanged(self, sender, event):
		if sender.Checked:
			self.value = sender.Tag  # Get the associated key
			
	def ButtonClicked(self, sender, args):
	    if sender == self.button2:  # Cancel
	        self.value = "RESET"
	    elif sender == self.button1:  # Make new series
	        checked_values = []  # Create a list to store ticks
	        for tick_box in self.tick_boxes:
	            if tick_box.Checked:
	                checked_values.append(tick_box.Tag)  # Store the value associated with the ticks
	        self.value = checked_values  # Output the list of ticks
	    self.Close()
	    
# Call the form
form = CreateWindow()
Application.Run(form)
if form.value == "RESET":
	OUT = form.value
else:
	OUT = form.value

This is pretty much it with the links and my office logo and stuff removed which should make zero difference to this.

I still get the first item in the list if I click the X at the top right of the pop up.

The buttons work as expected but the X
image

Gives me this:

image

Oh… and altho it says radio button it’s obviously tick boxes.
Reason is I wrote the same code for something with radio buttons and I’ve been too lazy to change it all :smiley:

So, one of my clever friends who is a real programmer, not a pretend one like me… said to delete:

def radioButton_CheckedChanged(self, sender, event):
		if sender.Checked:
			self.value = sender.Tag  # Get the associated key

AND where it’s called… so I did and now the X gives null :smiley:

Lesson of this story : If you’re going to re-purpose code, pay more attention to each function! :smiley:

Yay!

1 Like