与派生的 IronPython Windows 中的表单控件交互 class
Interacting with Windows Form controls in derived IronPython class
我正在学习如何将 IronPython 与 C# 结合使用。我想将一个简单的 windows 表单合并到我的应用程序中,因此我决定将它们放在一个单独的 C# 项目中,并将其编译为我在 python 项目中引用的 dll。我想创建引用 windows 形式 class 的子 class,以便我可以在 python 中创建事件处理程序。现在我有了第一步:
import clr
import sys
import threading
import random
import time
clr.AddReference('System.Drawing')
clr.AddReference('System.Windows.Forms')
clr.AddReference('CustomForm')
from System.Drawing import *
from System.Windows.Forms import *
from System.IO import *
from System import EventHandler
from CustomForm import *
from threading import Lock, Semaphore, Thread
from Queue import PriorityQueue
#Set up some global variables
NUM_DOCTORS = 3
MAX_CAPACITY = 10
PRIORITY_HIGH = 1
PRIORITY_MEDIUM = 2
PRIORITY_LOW = 3
PRIORITY_NONE = -1
#TODO: Fix all print statements once form can be referenced
class MyForm(Form1):
def __init__(self):
# Create child controls and initialize form
super(MyForm, self).__init__()
self.InitializeComponent()
self.input_button.Click += self.input_button_Click
print "Here right now"
self.admin = None
self.started = False
def setAdmin(self, ad):
self.admin = ad
def input_button_Click(self, sender, e):
print "hello click"
if not self.started:
self.admin.start()
self.started = not self.started
name = self.input_box.Text
#acquire the lock here, can't do it in the method or it will block
self.admin.lock.acquire()
self.admin.addPatient(name)
self.admin.lock.release()
print "is this working?"
self.input_box.Clear()
class Patient():
def __init__(self, patient_name):
#set up the severity of the illness
self.name = patient_name
#set up illness -> random time from 1-60 seconds
self.illness = random.randint(1,60)
self.priority = random.randint(1,3)
def getIllness(self):
return self.illness
def getName(self):
return self.name
def getPriority(self):
return self.priority
class Doctor(Thread):
def __init__(self, administrator, patient = None):
self.curr_patient = patient
self.admin = administrator
def healPatient(self):
sleep_time = self.curr_patient.getIllness()
#heal the patient by sleeping with how long it takes to cure illness
time.sleep(sleep_time)
def setPatient(self, patient):
self.curr_patient = patient
def run(self):
#grab a patient, heal them, and report the results
self.curr_patient = self.admin.getPatientFromQueue()
healPatient()
self.admin.reportResults(self.curr_patient)
class Administrator(Thread):
def __init__(self, form):
self.num_doctors = NUM_DOCTORS
self.lock = Lock()
self.patient_queue = PriorityQueue()
self.hospital_status = []
self.parent = form
self.waiting_room = []
#potential replacement for pq.qsize()
self.num_patients = 0
def run(self):
#first time
for i in range(NUM_DOCTORS):
d = Doctor(self)
d.start()
num_doctors -= 1
def getPatientFromQueue(self):
#grab a patient from the queue safely
if self.patient_queue.qsize() >= 1:
return patient_queue.get()
else:
return None
def reportResults(self, patient):
#update master list
with self.lock:
self.hospital_status.remove(patient)
self.admitPatient()
#change this for outcome
self.parent.status_box.Text += "\n" + patient.getName() + " is released"
printStatus()
self.num_doctors += 1
while self.num_doctors < 0:
d = Doctor(self)
d.start()
self.num_docters -= 1
def addPatient(self, name):
#add a patient if possible
p = Patient(name)
if len(self.hospital_status) < MAX_CAPACITY:
self.hospital_status.append(p)
self.patient_queue.put((p, p.getPriority()))
self.parent.status_box.Text += "\nPlease come in."
else:
#check the waiting list
self.waiting_room.append(p)
self.parent.status_box.Text += "\nPlease take a seat in the waiting room."
def admitPatient(self):
#check the waiting room -> admit patient if there otherwise do nothing
if len(self.waiting_room) > 0:
p = self.waiting_room.pop()
self.addPatient(p)
def printStatus(self):
#only called when lock is had
for p in self.hospital_status:
self.parent.status_box.Text += p.getName() + "-Priority-" + p.getPriority()
#print p.getName() + "-Priority-" + p.getPriority()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
form = MyForm()
admin = Administrator(form)
form.admin = admin
Application.Run(form)
我自己的表单只是 Form1,并由 python class MyForm 继承。当我 运行 这样做时,我在 C# 中制作的表单可以正确显示,但我找不到我应该如何与控件进行交互。表格显示为:
我希望能够听到按下按钮的声音并从顶部的文本框中读取内容。状态将打印在较大的富文本框中。我真的很感激任何意见。提前致谢!
更新 1:我认为我的问题的答案与找到的答案类似 here。我已将我的组件和方法的访问修饰符更改为 public,现在它们出现了。如果我的问题得到解决,我会更新这个。
更新 2:我现在可以看到这些组件,但我不确定我应该如何与它们交互。我应该将它们绑定到 MyForm 的 python init() 函数中的变量吗?
更新 3:我似乎已经很好地引用了这些组件(SEEM TO),但现在我注意到事件处理似乎已关闭。我已经包含了更多我正在使用的代码。请原谅线程逻辑等的任何潜在问题,因为我还没有解决这个问题并且可以自己解决。我似乎无法得到的是事件处理。一如既往,我非常感谢任何意见并提前致谢!
以下是对我有用的方法:
我制作了一个 Windows 表单项目(称为 FormProject
),它看起来与您的屏幕截图中的完全一样。我调用了输入文本框input_box
、按钮input_button
和状态文本框output_box
。这些控件中的每一个都是完全被动的(在 C# 中没有订阅事件)。
我通过在“设计”视图中转到它们的每个属性并选择 Modifiers = Public
来制作所有这些控件 public (默认值为 Private
)。 确保您的表单的 class 也是 public。
我将项目构建为 DLL,正如您已经知道的那样。
我编写了以下 IronPython 代码:(我将此代码放在与 FormProject
项目相同的解决方案中的单独项目中,但我确信无论您已经拥有的任何设置都可以正常工作)
记住你的CustomForm
就是我的FormProject
。
import clr
import sys
clr.AddReference('System.Windows.Forms')
clr.AddReferenceToFileAndPath('C:/Full/Path/To/Compiled/FormProject.dll')
from System.Windows.Forms import *
from FormProject import *
class MyForm(Form1):
def __init__(self):
super(MyForm, self).__init__()
self.input_button.Click += self.input_button_Click
def input_button_Click(self, sender, e):
self.output_box.Text += "Status: Tried to sign in with Name: \"" + self.input_box.Text + "\"\r\n"
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
form = MyForm()
Application.Run(form)
我不确定为什么在您的 MyForm
构造函数中您尝试调用 self.InitializeComponent()
,因为 (1) Form1.InitializeComponent()
是私有的,因此派生的 classes,并且 (2) 调用 super(MyForm, self).__init__()
已经通过 Form1
的构造函数,它调用 Form1.InitializeComponent
。所以在我的代码中我只是把它拿出来了(我的代码工作得很好)。
如果你运行这个Python代码,点击按钮应该向输出框添加文本(根据输入框的文本),证明我写了一个事件处理程序和将其订阅到控件的事件,全部在 Python.
中
希望对您有所帮助!
我正在学习如何将 IronPython 与 C# 结合使用。我想将一个简单的 windows 表单合并到我的应用程序中,因此我决定将它们放在一个单独的 C# 项目中,并将其编译为我在 python 项目中引用的 dll。我想创建引用 windows 形式 class 的子 class,以便我可以在 python 中创建事件处理程序。现在我有了第一步:
import clr
import sys
import threading
import random
import time
clr.AddReference('System.Drawing')
clr.AddReference('System.Windows.Forms')
clr.AddReference('CustomForm')
from System.Drawing import *
from System.Windows.Forms import *
from System.IO import *
from System import EventHandler
from CustomForm import *
from threading import Lock, Semaphore, Thread
from Queue import PriorityQueue
#Set up some global variables
NUM_DOCTORS = 3
MAX_CAPACITY = 10
PRIORITY_HIGH = 1
PRIORITY_MEDIUM = 2
PRIORITY_LOW = 3
PRIORITY_NONE = -1
#TODO: Fix all print statements once form can be referenced
class MyForm(Form1):
def __init__(self):
# Create child controls and initialize form
super(MyForm, self).__init__()
self.InitializeComponent()
self.input_button.Click += self.input_button_Click
print "Here right now"
self.admin = None
self.started = False
def setAdmin(self, ad):
self.admin = ad
def input_button_Click(self, sender, e):
print "hello click"
if not self.started:
self.admin.start()
self.started = not self.started
name = self.input_box.Text
#acquire the lock here, can't do it in the method or it will block
self.admin.lock.acquire()
self.admin.addPatient(name)
self.admin.lock.release()
print "is this working?"
self.input_box.Clear()
class Patient():
def __init__(self, patient_name):
#set up the severity of the illness
self.name = patient_name
#set up illness -> random time from 1-60 seconds
self.illness = random.randint(1,60)
self.priority = random.randint(1,3)
def getIllness(self):
return self.illness
def getName(self):
return self.name
def getPriority(self):
return self.priority
class Doctor(Thread):
def __init__(self, administrator, patient = None):
self.curr_patient = patient
self.admin = administrator
def healPatient(self):
sleep_time = self.curr_patient.getIllness()
#heal the patient by sleeping with how long it takes to cure illness
time.sleep(sleep_time)
def setPatient(self, patient):
self.curr_patient = patient
def run(self):
#grab a patient, heal them, and report the results
self.curr_patient = self.admin.getPatientFromQueue()
healPatient()
self.admin.reportResults(self.curr_patient)
class Administrator(Thread):
def __init__(self, form):
self.num_doctors = NUM_DOCTORS
self.lock = Lock()
self.patient_queue = PriorityQueue()
self.hospital_status = []
self.parent = form
self.waiting_room = []
#potential replacement for pq.qsize()
self.num_patients = 0
def run(self):
#first time
for i in range(NUM_DOCTORS):
d = Doctor(self)
d.start()
num_doctors -= 1
def getPatientFromQueue(self):
#grab a patient from the queue safely
if self.patient_queue.qsize() >= 1:
return patient_queue.get()
else:
return None
def reportResults(self, patient):
#update master list
with self.lock:
self.hospital_status.remove(patient)
self.admitPatient()
#change this for outcome
self.parent.status_box.Text += "\n" + patient.getName() + " is released"
printStatus()
self.num_doctors += 1
while self.num_doctors < 0:
d = Doctor(self)
d.start()
self.num_docters -= 1
def addPatient(self, name):
#add a patient if possible
p = Patient(name)
if len(self.hospital_status) < MAX_CAPACITY:
self.hospital_status.append(p)
self.patient_queue.put((p, p.getPriority()))
self.parent.status_box.Text += "\nPlease come in."
else:
#check the waiting list
self.waiting_room.append(p)
self.parent.status_box.Text += "\nPlease take a seat in the waiting room."
def admitPatient(self):
#check the waiting room -> admit patient if there otherwise do nothing
if len(self.waiting_room) > 0:
p = self.waiting_room.pop()
self.addPatient(p)
def printStatus(self):
#only called when lock is had
for p in self.hospital_status:
self.parent.status_box.Text += p.getName() + "-Priority-" + p.getPriority()
#print p.getName() + "-Priority-" + p.getPriority()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
form = MyForm()
admin = Administrator(form)
form.admin = admin
Application.Run(form)
我自己的表单只是 Form1,并由 python class MyForm 继承。当我 运行 这样做时,我在 C# 中制作的表单可以正确显示,但我找不到我应该如何与控件进行交互。表格显示为:
我希望能够听到按下按钮的声音并从顶部的文本框中读取内容。状态将打印在较大的富文本框中。我真的很感激任何意见。提前致谢!
更新 1:我认为我的问题的答案与找到的答案类似 here。我已将我的组件和方法的访问修饰符更改为 public,现在它们出现了。如果我的问题得到解决,我会更新这个。
更新 2:我现在可以看到这些组件,但我不确定我应该如何与它们交互。我应该将它们绑定到 MyForm 的 python init() 函数中的变量吗?
更新 3:我似乎已经很好地引用了这些组件(SEEM TO),但现在我注意到事件处理似乎已关闭。我已经包含了更多我正在使用的代码。请原谅线程逻辑等的任何潜在问题,因为我还没有解决这个问题并且可以自己解决。我似乎无法得到的是事件处理。一如既往,我非常感谢任何意见并提前致谢!
以下是对我有用的方法:
我制作了一个 Windows 表单项目(称为
FormProject
),它看起来与您的屏幕截图中的完全一样。我调用了输入文本框input_box
、按钮input_button
和状态文本框output_box
。这些控件中的每一个都是完全被动的(在 C# 中没有订阅事件)。我通过在“设计”视图中转到它们的每个属性并选择
Modifiers = Public
来制作所有这些控件 public (默认值为Private
)。 确保您的表单的 class 也是 public。我将项目构建为 DLL,正如您已经知道的那样。
我编写了以下 IronPython 代码:(我将此代码放在与
FormProject
项目相同的解决方案中的单独项目中,但我确信无论您已经拥有的任何设置都可以正常工作)
记住你的CustomForm
就是我的FormProject
。
import clr
import sys
clr.AddReference('System.Windows.Forms')
clr.AddReferenceToFileAndPath('C:/Full/Path/To/Compiled/FormProject.dll')
from System.Windows.Forms import *
from FormProject import *
class MyForm(Form1):
def __init__(self):
super(MyForm, self).__init__()
self.input_button.Click += self.input_button_Click
def input_button_Click(self, sender, e):
self.output_box.Text += "Status: Tried to sign in with Name: \"" + self.input_box.Text + "\"\r\n"
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
form = MyForm()
Application.Run(form)
我不确定为什么在您的 MyForm
构造函数中您尝试调用 self.InitializeComponent()
,因为 (1) Form1.InitializeComponent()
是私有的,因此派生的 classes,并且 (2) 调用 super(MyForm, self).__init__()
已经通过 Form1
的构造函数,它调用 Form1.InitializeComponent
。所以在我的代码中我只是把它拿出来了(我的代码工作得很好)。
如果你运行这个Python代码,点击按钮应该向输出框添加文本(根据输入框的文本),证明我写了一个事件处理程序和将其订阅到控件的事件,全部在 Python.
中希望对您有所帮助!