I am trying to add UserControl to a WinForm using PythonNet but not having any luck. For testing, I added a button and that shows up but not the UserControl and I am not sure what I a doing wrong.
All the code can be placed into one py file. I broke into a few sections hoping it will be easier to read.
USER CONTROL
class Field(WinForms.UserControl):
def __init__(self):
self.InitializeComponents()
pass
def InitializeComponents(self):
self.components = System.ComponentModel.Container()
self.label = WinForms.Label()
self.textBox = WinForms.Label()
## Label
# self.label.Anchor = ((WinForms.AnchorStyles)(
# ((WinForms.AnchorStyles.Top | WinForms.AnchorStyles.Bottom)
# | WinForms.AnchorStyles.Left)))
self.label.AutoSize = True
self.label.Location = System.Drawing.Point(3, 7)
self.label.Name = "label"
self.label.Size = System.Drawing.Size(29, 13)
self.label.TabIndex = 0
self.label.Text = "label"
## TextBox
# self.textBox.Anchor = ((WinForms.AnchorStyles)(
# (((WinForms.AnchorStyles.Top | WinForms.AnchorStyles.Bottom)
# | WinForms.AnchorStyles.Left)
# | WinForms.AnchorStyles.Right)))
# self.textBox.Location = System.Drawing.Point(115, 3)
self.textBox.Name = "textBox"
self.textBox.Size = System.Drawing.Size(260, 20)
self.textBox.TabIndex = 1
## Control
self.AutoScaleMode = WinForms.AutoScaleMode.Font
self.Controls.Add(self.textBox)
self.Controls.Add(self.label)
self.Name = "Field"
self.Size = System.Drawing.Size(378, 26)
# self.PerformLayout()
PARENT FORM
class ParentForm(WinForms.Form):
def __init__(self):
self.InitializeComponents()
# region Form Design
def InitializeComponents(self):
self.components = System.ComponentModel.Container()
self.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
self.ClientSize = System.Drawing.Size(385, 180)
self.Name = "ParentForm"
self.Text = "Parent Form"
self.field1 = Field()
self.field1.Location = Point(13, 13)
self.field1.Name = "field1"
self.field1.Size = Size(378, 26)
self.field1.TabIndex = 1
self.Controls.Add(self.field1)
self.button1 = WinForms.Button()
self.button1.Location = Point(13, 50)
self.button1.Size = Size(50, 20)
self.button1.Text = "Button1"
self.Controls.Add(self.button1)
pass
def Dispose(self):
self.components.Dispose()
WinForms.Form.Dispose(self)
ENTRY POINT AND IMPORTS
import clr
import System
import System.Windows.Forms as WinForms
from System.IO import File
from System.Text import Encoding
from System.Drawing import Color, Point, Size
from System.Threading import ApartmentState, Thread, ThreadStart
def appThread():
app = ParentForm()
WinForms.Application.Run(app)
app.Dispose()
def appEntry():
thread = Thread(ThreadStart(appThread))
thread.SetApartmentState(ApartmentState.STA)
thread.Start()
thread.Join()
if __name__ == '__main__':
appEntry()
Related
I can't make graph with qt6 beacouse when I set values it gives me error: numpy.core._exceptions._UFuncNoLoopError: ufunc 'fmin' did not contain a loop with signature matching types (dtype('<U1'), dtype('<U1')) -> None
Theres my code:
import sys
from PySide6.QtWidgets import QApplication
from PySide6 import *
import pyqtgraph as pg
uiclass, baseclass = pg.Qt.loadUiType("mainwindow.ui")
class MainWindow(uiclass, baseclass):
def __init__(self):
super().__init__()
self.setupUi(self)
self.plot([1,2,3,4,5,6,7,8,9,10], [20,20,20,20,20,20,20,20,20,20])
self.pushButton.clicked.connect(lambda: self.changeColorTeeth1())
self.pushButton_2.clicked.connect(lambda: self.changeColorTeeth2())
self.pushButton_3.clicked.connect(lambda: self.changeColorTeeth3())
self.pushButton_4.clicked.connect(lambda: self.changeColorTeeth4())
self.pushButton_5.clicked.connect(lambda: self.changeColorTeeth5())
self.pushButton_6.clicked.connect(lambda: self.changeColorTeeth6())
self.SaveGraphButton.clicked.connect(lambda: self.Save())
def plot(self, teethsize, height):
self.graphWidget.plot(teethsize, height)
self.graphWidget_2.plot(teethsize, height)
def Save(self):
print("Save runned!")
Teeth1 = self.Teeth1.toPlainText()
Teeth2 = self.Teeth2.toPlainText()
Teeth3 = self.Teeth3.toPlainText()
Teeth4 = self.Teeth4.toPlainText()
Teeth5 = self.Teeth5.toPlainText()
Teeth6 = self.Teeth6.toPlainText()
Teeth7 = self.Teeth7.toPlainText()
Teeth8 = self.Teeth8.toPlainText()
Teeth9 = self.Teeth9.toPlainText()
Teeth10 = self.Teeth10.toPlainText()
Teeth11 = self.Teeth11.toPlainText()
Teeth12 = self.Teeth12.toPlainText()
Teeth13 = self.Teeth13.toPlainText()
Teeth14 = self.Teeth14.toPlainText()
self.plot([Teeth1,Teeth2,Teeth3,Teeth4,Teeth5,Teeth6,Teeth7,Teeth8,Teeth9,Teeth10,Teeth11,Teeth12,Teeth13,Teeth14], [20,20,20,20,20,20,20,20,20,20,20,20,20,20])
def changeColorTeeth1(self):
g = open('config.txt', 'r')
buttonClicked = int(g.read())
print("Button State:", buttonClicked)
g.close()
f = open('config.txt', 'w')
if buttonClicked == 0:
self.pushButton.setStyleSheet(f"background-color : orange;")
buttonClicked = 1
elif buttonClicked == 1:
self.pushButton.setStyleSheet(f"background-color : red;")
buttonClicked = 2
elif buttonClicked == 2:
self.pushButton.setStyleSheet(f"background-color : white;")
buttonClicked = 0
b = f.write(str(buttonClicked))
f.close()
...
I tried to add str and int but it still doesn't worked!
To give some background, I am attempting to use Python to give some of my users an interface through a third-party program (that already has IronPython embedded) to add, edit, and delete records from a SQL Server database.
I've received good assistance from one member here about Python .NET Winforms so I am attempting to get some more assistance. My goal is to populate a DataGridView (dgv) with records from a table. Seems pretty simple. However, when I run the code, my dgv is just an empty container.
I could use some assistance or better yet, point me in the right direction to find the answer. I am willing to learn.
import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
clr.AddReference("System.Data")
clr.AddReference("System.Globalization")
from System.Windows.Forms import *
from System.Drawing import *
from System.Data import *
from System.Data.SqlClient import *
from System.Globalization import *
class MyForm(Form):
def __init__(self):
# Setup the form
self.Text = "Calculated Control Limits Form"
self.StartPosition = FormStartPosition.CenterScreen # https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.form.startposition?view=net-5.0
# Create & configure the DataGridView label
self.setupDataGridViewLabel()
# Create, configure, and populate data for the DataGridView
self.setupDataGridView()
self.PopulateDataGridView("SELECT * FROM SPC_CALCULATED_CONTROL_LIMITS")
# Create & configure a line seperator
self.setupSeperator()
# Create & configure a Label to grab the users Employee ID
self.setupEmployeeIDLabel()
# Create & configure a label for the Lower Control Limit Label
self.Load_LCL_Label()
# Create & configure a TextBox for the Lower Control Limit
self.Load_LCL_TextBox()
# Create & configure a label for the Target Mean
self.LoadTargetMeanLabel()
# Create & configure a TextBox for the Target Mean
self.LoadTargetMeanTextBox()
# Create & configure a label for the Upper Control Limit
self.Load_UCL_Label()
# Create & configure a TextBox for the Upper Control Limit
self.Load_UCL_TextBox()
# Create & configure a label for the Comment
self.LoadCommentLabel()
# Create a TextBox for the Comment
self.LoadCommentTextBox()
# Create & configure the button
self.LoadButton()
# Register the event handler
self.button.Click += self.button_Click
self.Size = Size (550, self.button.Bottom + self.button.Height + 15)
#Load the Controls to the Form
self.Controls.Add(self.lblCCL)
self.Controls.Add(self.dgvCCL)
self.Controls.Add(self.button)
self.Controls.Add(self.lblSep)
self.Controls.Add(self.lblEmpID)
self.Controls.Add(self.lblLCL)
self.Controls.Add(self.txtLCL)
self.Controls.Add(self.lblTarget)
self.Controls.Add(self.txtTarget)
self.Controls.Add(self.lblUCL)
self.Controls.Add(self.txtUCL)
self.Controls.Add(self.lblComment)
self.Controls.Add(self.txtComment)
def button_Click(self, sender, args):
self.Close()
def setupDataGridView(self):
self.dgvCCL = DataGridView()
self.dgvCCL.AllowUserToOrderColumns = True
self.dgvCCL.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize
self.dgvCCL.Location = Point(self.lblCCL.Left, self.lblCCL.Bottom + 5)
self.dgvCCL.Size = Size(500, 250)
self.dgvCCL.TabIndex = 3
#self.dgvCCL.ColumnCount = len(headers)
self.dgvCCL.ColumnHeadersVisible = True
def setupSeperator(self):
self.lblSep = Label()
self.lblSep.Size = Size(500, 2)
self.lblSep.BackColor = Color.DarkGray
self.lblSep.BorderStyle = BorderStyle.Fixed3D
self.lblSep.Location = Point(self.dgvCCL.Left, self.dgvCCL.Bottom + 10)
def setupDataGridViewLabel(self):
self.lblCCL = Label()
self.lblCCL.Text = "Calculated Control Limits View"
self.lblCCL.Font = Font(self.Font, FontStyle.Bold)
self.lblCCL.Location = Point(10, 10)
self.lblCCL.BorderStyle = 0 # BorderStyle.None --> https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.borderstyle?view=net-5.0
self.lblCCL.Size = Size(self.lblCCL.PreferredWidth, self.lblCCL.PreferredHeight)
def setupEmployeeIDLabel(self):
self.lblEmpID = Label()
self.lblEmpID.Text = 'login.computeruser.upper()'
self.lblEmpID.Font = Font(self.Font, FontStyle.Bold)
self.lblEmpID.Size = Size(self.lblEmpID.PreferredWidth, self.lblEmpID.PreferredHeight)
self.lblEmpID.Location = Point(self.dgvCCL.Right - self.lblEmpID.Width, self.dgvCCL.Top - 15)
self.lblEmpID.BorderStyle = 0
def Load_LCL_Label(self):
self.lblLCL = Label()
self.lblLCL.Text = 'Lower Control Limit'
self.lblLCL.Size = Size(self.lblLCL.PreferredWidth, self.lblLCL.PreferredHeight)
self.lblLCL.Location = Point(self.lblSep.Left + 65, self.lblSep.Top + 15)
self.lblLCL.BorderStyle = 0
def Load_LCL_TextBox(self):
self.txtLCL = TextBox()
self.txtLCL.Size = Size(100, 50)
self.txtLCL.Location = Point(self.lblLCL.Left, self.lblLCL.Bottom + 3)
def LoadTargetMeanLabel(self):
self.lblTarget = Label()
self.lblTarget.Text = 'Target Mean'
self.lblTarget.Size = Size(self.lblLCL.PreferredWidth, self.lblLCL.PreferredHeight)
self.lblTarget.Location = Point(self.lblLCL.Left + 125, self.lblSep.Top + 15)
self.lblTarget.BorderStyle = 0
def LoadTargetMeanTextBox(self):
self.txtTarget = TextBox()
self.txtTarget.Size = Size(100, 50)
self.txtTarget.Location = Point(self.lblLCL.Left + 125, self.lblLCL.Bottom + 3)
def Load_UCL_Label(self):
self.lblUCL = Label()
self.lblUCL.Text = 'Upper Control Limit'
self.lblUCL.Size = Size(self.lblUCL.PreferredWidth, self.lblUCL.PreferredHeight)
self.lblUCL.Location = Point(self.lblTarget.Left + 125, self.lblSep.Top + 15)
self.lblUCL.BorderStyle = 0
def Load_UCL_TextBox(self):
self.txtUCL = TextBox()
self.txtUCL.Size = Size(100, 50)
self.txtUCL.Location = Point(self.lblTarget.Left + 125, self.lblLCL.Bottom + 3)
def LoadCommentLabel(self):
self.lblComment = Label()
self.lblComment.Text = 'Comment'
self.lblComment.Size = Size(self.lblUCL.PreferredWidth, self.lblUCL.PreferredHeight)
self.lblComment.Location = Point(self.lblSep.Left, 350)
self.lblComment.BorderStyle = 0
def LoadCommentTextBox(self):
self.txtComment = TextBox()
self.txtComment.Multiline = True
self.txtComment.Size = Size(500, 50)
self.txtComment.Location = Point(self.lblSep.Left, self.lblComment.Bottom + 5)
def LoadButton(self):
self.button = Button()
self.button.Size = Size(100, 30)
self.button.Location = Point(self.lblSep.Left, self.txtComment.Bottom + 10)
self.button.Text = "Click Me!"
def PopulateDataGridView(self, selectcommand):
bs = BindingSource()
try:
connectionstring = "YourSQLServerConnectionString"
# Create a new data adapter based on the specified query.
da = SqlDataAdapter(selectcommand, connectionstring)
# Create a command builder to generate SQL update, insert, and delete commands based on selectCommand.
cb = SqlCommandBuilder(da)
# Populate a new data table and bind it to the BindingSource.
dt = DataTable()
Locale = CultureInfo.InvariantCulture
da.Fill(dt)
bs.DataSource = dt
# Resize the DataGridView columns to fit the newly loaded content.
self.dgvCCL.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader)
#String connectionString =
#"Data Source=<SQL Server>;Initial Catalog=Northwind;" +
#"Integrated Security=True";
#// Create a new data adapter based on the specified query.
#dataAdapter = new SqlDataAdapter(selectCommand, connectionString);
#// Create a command builder to generate SQL update, insert, and
#// delete commands based on selectCommand.
#SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);
#// Populate a new data table and bind it to the BindingSource.
#DataTable table = new DataTable
#{
# Locale = CultureInfo.InvariantCulture
#};
#dataAdapter.Fill(table);
#bindingSource1.DataSource = table;
#// Resize the DataGridView columns to fit the newly loaded content.
#dataGridView1.AutoResizeColumns(
#DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);
except SqlException:
Messagebox.Show("Something happened.")
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(MyForm())
This is my current project (Python 3.8). Your supposed to be able to draw things on your screen. This is not my full version. Its just for explanation purposes. The problem is that if you run run.py it doesn't clear the screen. Shouldn't the new Frame just push the old one out of frame? Do you know what my problem is?
main.py:
import os
import time
from datetime import datetime
import logging
import ctypes
class ConsoleGameEngine:
def __init__(self, windowWidth, windowHeight):
logging.basicConfig(filename=f'debug\{datetime.now().strftime("%H-%M-%S")}-main.log',level=logging.DEBUG)
self.screenWidth = windowWidth
self.screenHeight = windowHeight
self.var = ""
self.pixel = u"\u2591"#u"\u25A1"
self.lightShade = u"\u2591"
self.mediumShade = u"\u2592"
self.darkShade = u"\u2593"
os.system(f'mode con: cols={self.windowWidth} lines={self.windowHeight}')
"""
SCREEN ACCESS:
self.screen[y][x]
"""
self.clearScreenVar = [[" " for w in range(self.screenWidth)] for h in range(self.screenHeight)]
self.screen = self.clearScreenVar
def clearScreen(self):
"""
for y in range(self.windowHeight):
for x in range(self.windowHeight):
self.screen[y][x] = " "
"""
self.screen = self.clearScreenVar
def drawPixel(self,x,y,shade=u"\u2591"):
try:
self.screen[y][x] = shade
except Exception as e:
logging.warning(datetime.now().strftime("%H:%M:%S~")+str(e)+f"~Failed drawing pixel at x: {x} and/or y: {y}")
def sleep(self, t = 1):
time.sleep(t)
def printScreen(self):
print("".join(["".join(x) for x in self.screen]))
run.py:
from main import ConsoleGameEngine
win = ConsoleGameEngine(120, 40)
x = 0
while True:
win.drawPixel(x,20)
win.printScreen()
win.sleep(0.1)
win.clearScreen()
x += 1
I started today with qt compiler, so I don't have much experience in building gui. My project is about to create dynamic smart check boxes to define axes and at the end to plot several subplots to a figure.
I tried to create dynamic combo boxes that change every time I change my current selection in the combo box.
The big issue is that it crash every time i try to change a selection in the combo box.
I tried to use .clear() method but it crash every time I clicked on it.
Edit: I changed the code to make producible code. After clicking on "Load Files", you will be able the combo boxes filled. If you will change the combo box "Choose message" for example, the python crash.
The GUI
# ------------------------------------------------- -----
# ---------------------- main.py ------------------- ----
# --------------------------------------------- ---------
from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.uic import loadUi
from PyQt5.QtCore import pyqtSlot
import threading , os, subprocess, importlib, platform
# Decode_class = 'MAVLinkBinFileDecoder'
# Module = importlib.import_module(Decode_class)
from matplotlib.backends.backend_qt5agg import (NavigationToolbar2QT as NavigationToolbar )
import numpy as np
import random
class MatplotlibWidget(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
loadUi("gui.ui", self)
self.setWindowTitle ( "PyQt5 & Matplotlib Example GUI" )
self.loadfiles = 0
self.first_run = 0
self.progressBar.setProperty("value", 0)
# self.pushButton_load_files.setEnabled(False)
self.pushButton_add_to_graph.setEnabled(False)
self.pushButton_choose_xml_file.clicked.connect(self.open_xml_FileNamesDialog)
self.pushButton_choose_bin_files.clicked.connect(self.open_bin_FileNamesDialog)
self.pushButton_load_files.clicked.connect(self.load_files)
self.comboBox_choose_file.currentIndexChanged.connect(self.selectionchange_file)
self.comboBox_message.currentIndexChanged.connect(self.selectionchange_message)
self.comboBox_system_id.currentIndexChanged.connect(self.selectionchange_system_id)
self.pushButton_save_plot.clicked.connect(self.update_graph)
self.file_to_graph_demo = [({'HEARTBEAT':[{'type':[12],'autopilot':[0]},{'type':[2,2,0],'autopilot':[0,0,0]}], 'CHAMBER_STATUS':[{'time_boot_ms':[1,1,1], 'chamber_num':[1,2,3]}], 'ATTITUDE':[{'test':[0,0,0,],'check':[1,1,1]}, {'test':[0,0,0,],'check':[1,1,1]}, 0 , 0, {'test':[0,0,0,],'check':[1,1,1]}]},'test')]
self.addToolBar(NavigationToolbar(self .MplWidget.canvas, self))
#pyqtSlot()
def open_xml_FileNamesDialog(self):
self.loadfiles += 1
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
self.filename, _ = QFileDialog.getOpenFileNames(self, "QFileDialog.getOpenFileNames()", "",
"Xml Files (*.xml)", options=options)
if self.loadfiles == 2:
self.pushButton_load_files.setEnabled(True)
self.pushButton_choose_xml_file.setVisible(False)
#pyqtSlot()
def open_bin_FileNamesDialog(self):
self.loadfiles += 1
options = QFileDialog.Options()
options |= QFileDialog.DontUseNativeDialog
self.list_of_file_paths, _ = QFileDialog.getOpenFileNames(self, "QFileDialog.getOpenFileNames()", "",
"Bin Files (*.bin)", options=options)
if self.loadfiles == 2:
self.pushButton_load_files.setEnabled(True)
self.pushButton_choose_bin_files.setVisible(False)
#pyqtSlot()
def load_files(self):
# parse = Module.Logic_bin_to_mat_parser(self.filename[0])
# parse.generate_dialect_from_xml() # Run Mavgenerate xml function
# value = 19
# self.progressBar.setProperty("value", value)
# self.file_to_graph = []
# for path in self.list_of_file_paths: # Parse and create Matlab from each bin file
# parse.decode_messages(path)
# parse.create_dictionary_of_amount_of_messages_by_type()
# parse.parse_bin_to_mat()
# self.file_to_graph.append((parse.save, parse.file_base_name))
# parse.convert_parse_dictionary_to_mat()
# value += (100 - 20) / len(self.list_of_file_paths)
# self.progressBar.setProperty("value", value)
# value = 100
# self.progressBar.setProperty("value", value)
# self.pushButton_load_files.setVisible(False)
# self.progressBar.setVisible(False)
for option in self.file_to_graph_demo:
self.comboBox_choose_file.addItem(option[1])
#pyqtSlot()
def selectionchange_file(self):
self.first_run += 1
combobox_enty = self.comboBox_choose_file.currentText()
self.file_idx = self.comboBox_choose_file.findText(combobox_enty)
list_of_messages = []
for message in self.file_to_graph_demo[self.file_idx][0].items():
list_of_messages.append(message[0])
if self.first_run >= 1:
self.comboBox_message.clear()
self.comboBox_message.addItems(list_of_messages)
#pyqtSlot()
def selectionchange_message(self):
self.first_run += 1
self.combobox_entry_message = self.comboBox_message.currentText()
self.message_idx = self.comboBox_message.findText(self.combobox_entry_message)
list_of_system_ids = []
count = 0
for idx, system_id in enumerate(self.file_to_graph_demo[self.file_idx][0][self.combobox_entry_message]):
if system_id != 0:
count += 1
list_of_system_ids.append(str(idx+1))
if self.first_run >= 2:
self.comboBox_system_id.clear()
self.comboBox_system_id.addItems(list_of_system_ids)
#pyqtSlot()
def selectionchange_system_id(self):
self.combobox_entry_system_id = int(self.comboBox_system_id.currentText())-1
self.system_id_idx = self.comboBox_system_id.findText(str(self.combobox_entry_system_id))
for field in self.file_to_graph_demo[self.file_idx][0][self.combobox_entry_message][self.system_id_idx]:
self.comboBox_y_axis.addItem(field)
self.comboBox_x_axis.addItem(field)
def update_graph(self):
fs = 500
f = random.randint(1, 100)
ts = 1 / fs
length_of_signal = 100
t = np . linspace (0, 1, length_of_signal )
cosinus_signal = np . cos ( 2 * np . pi * f * t )
sinus_signal = np . sin ( 2 * np . pi * f * t )
self.MplWidget.canvas.axes.clear()
self.MplWidget.canvas.axes.plot(t,cosinus_signal)
self.MplWidget.canvas.axes.plot(t,sinus_signal)
self.MplWidget.canvas.axes.legend(('cosinus', 'sinus'), loc='upper right')
self.MplWidget.canvas.axes.set_title(' Cosinus - Sinus Signal')
self.MplWidget.canvas.draw()
if __name__ == '__main__':
app=QApplication([])
app.setStyle('Fusion')
window=MatplotlibWidget()
window.show()
app.exec_()
Your issue seems to be in MatplotlibWidget.selectionchange_system_id(). You are trying to cast the current text of self.comboBox_system_id to an int, but this will cause an exception when the current text can't be converted. This is the case just after self.comboBox_system_id is cleared because at that point the current text of the combi box is an empty string. The easiest way to get around this is to test if the current text can be cast to an integer first before continuing, i.e.
def selectionchange_system_id(self):
if self.comboBox_system_id.currentText().isdigit():
self.combobox_entry_system_id = int(self.comboBox_system_id.currentText())-1
...
I'm a beginner in Python and have a trouble in running a python module in Rhino3D Grasshopper. The code in a Python module is shown as below.
An instance of Agent alone is working well but when I try to dla.update() with Timer in a next python module(which is simply executing dla.update()), I got the message saying that there is something wrong in self.pos = rs.EvaluateCurve(cirCrv, rndNum) and self.curAgent = Agent(self.cirCrv, self.cenPt, self.walkDist).
Is there a way to make this working ?
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
import ghpythonlib.components as gh
import random as rnd
class Agent :
def __init__(self, cirCrv, cenPt, walkDist):
self.cenPt = cenPt
self.walkDist = walkDist
rndNum = rnd.random()
self.pos = rs.EvaluateCurve(cirCrv, rndNum)
def randWalk(self) :
v = rs.VectorSubtract(rs.AddPoint(0,0,0), self.pos)
v1 = rs.VectorUnitize(v)
v2 = rs.VectorScale(v1, self.walkDist)
v3 = rs.VectorSubtract(self.pos, rs.AddPoint(0,0,0))
v4 = rs.VectorAdd(v3, gh.UnitZ(1))
rotAxis = rs.VectorSubtract(v4, v3)
newV1 = rs.VectorRotate(v2, rnd.uniform(-70, 70), rotAxis)
self.pos = rs.VectorAdd(self.pos, newV1)
def checkDist(self):
dist1 = rs.Distance(self.pos, rs.AddPoint(0,0,0))
return dist1
class dla :
def __init__(self, cirCrv, cenPt, walkDist):
self.Agents = []
self.cirCrv = cirCrv
self.cenPt = cenPt
self.walkDist = walkDist
self.curAgent = Agent(self.cirCrv, self.cenPt, self.walkDist)
self.pos =self.curAgent.pos
def update(self):
if self.curAgent.checkDist() < 1:
self.Agents.append(self.curAgent)
self.curAgent = Agent(self.cirCrv, self.cenPt, self.walkDist)
else:
self.curAgent.randWalk()
a = dla(cirCrv,cenPt,walkDist)