Python CLR WinForms - Opening another from from an existing form - python

I am having some extreme difficulty with something so simple. All I am trying to do is launch another Windows Form from an existing Windows Form in Python. I've tried everything I can think of and I cannot figure out. Below is a example program:
import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
clr.AddReference("System.ComponentModel")
from System.Windows.Forms import *
from System.Drawing import *
class MyForm(Form):
def __init__(self):
self.StartPosition = FormStartPosition.CenterScreen
self.btnTest = Button()
self.btnTest.Name = 'btnTest'
self.btnTest.Text = "Test"
self.btnTest.Size = Size(80, 30)
self.Controls.Add(self.btnTest)
self.btnTest.Click += self.Add_Control_Limits_Form_Click
def Add_Control_Limits_Form_Click(self, sender, args):
Application.Run(MySecondForm())
class MySecondForm(Form):
def __init__(self2):
self2.StartPosition = FormStartPosition.CenterScreen
self2.AutoScaleMode = AutoScaleMode.Font
self2.ClientSize = Size(800, 450)
self2.Text = "Form2"
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(MyForm())
Which, when I run it, it gives me this error message:
InvalidOperationException : Starting a second message loop on a single thread is not a valid operation. Use Form.ShowDialog instead.
I don't think it's as simple as just putting MySecondForm.ShowDialog() since I have this as a class. What am I missing?

I figured it out.
So, within the button click event, add these lines of code:
self.TopLevel = False
YF = YourForm()
YF.ShowDialog()
self.TopLevel = True
...if you want it modal. I did.
You don't need the Application.Run(MySecondForm()) code within the button click event.
Then, within your second form class, just initialize your form the way you want.

Related

Calling a method with another method within another class (calling Method_B within Class_B, with Method_A within Class_A)

I am a Maya user and I am currently writting an Auto-Rig.
I created different Classes for each major tasks of the tool. (ex: Class_UI, Class_Arms_Rig, etc..)
The problem I have is that I can't call a method from "Class_Joints" (the class that will generates every needed Joints) with my "Class_UI"
Here are the codes :
First the Class_UI
import sys
sys.path.append('G:\\3D2\\Script\\Auto_Rig')
import Class_Joints
import Class_Arms
import maya.cmds as mc
class Window_UI(object):
# Initializing global variables
def __init__(self):
# Getting acces to the different modules
self.Arms = Class_Arms.Arms_Rig()
self.Joints = Class_Joints.Gen_Joints()
# Create Ui
self.create_UI()
# Creating the UI
def create_UI(self):
# Create window
self.UI = mc.window(title='Auto-Rig Tool', w=(300), h=(350))
# Main layout
self.mainLayout = mc.menuBarLayout()
### Joints Option ###
# Create Joints Button
self.createJointsButton = mc.button(label='Create Joints', command=self.Joints.gen_arms_joints)
Window_UI()
mc.showWindow()
Then the Class_Joints :
import maya.cmds as mc
class Gen_Joints:
# Creating arm Jnts and the list of it
def gen_arms_joints(self):
self.shoulderJnt = mc.joint(absolute=True, position=[5,8,0], n='L_Shoulder_Jnt')
self.elbowJnt = mc.joint(absolute=True, position=[10,8,-1.5], n='L_Elbow_Jnt')
self.wristJnt = mc.joint(absolute=True, position=[15,8,0], n='L_Wrist_Jnt')
self.handcupJnt = mc.joint(absolute=True, position=[18,8,0], n='L_HandCup_Jnt')
self.jntList = mc.ls(self.shoulderJnt, self.elbowJnt, self.wristJnt, self.handcupJnt)
When I run the Class_UI Code, the button within the UI is supposed to run the gen_arms_joints method within the Class_Joints
But I get this error message : # Error: gen_arms_joints() takes exactly 1 argument (2 given) #
I know that self is an implicit argument here but I do not know how to avoid this error.
Thank you all for your time.
:D
Cordially, Luca.
Two things i would recommend you do. I dont use Maya but i have built apps with multiple different GUIs.
Every GUI I've used when it comes to buttons is the first argument is a reference to self, and then there is usually 1 or 2 more arguments passed in. Some pass the reference to the button itself while others pass a argument that holds event details. My guess is this is what is happening. When you click the button it is passing in an "event" object that hold details about what was clicked and other details.
To truly find out what is passed change your function signature to this and see what is logged.
def gen_arms_joints(self, mystery_second_arg):
print(type(mystery_second_arg), mystery_second_arg)
self.shoulderJnt = mc.joint(absolute=True, position=[5,8,0], n='L_Shoulder_Jnt')
self.elbowJnt = mc.joint(absolute=True, position=[10,8,-1.5], n='L_Elbow_Jnt')
self.wristJnt = mc.joint(absolute=True, position=[15,8,0], n='L_Wrist_Jnt')
self.handcupJnt = mc.joint(absolute=True, position=[18,8,0], n='L_HandCup_Jnt')
self.jntList = mc.ls(self.shoulderJnt, self.elbowJnt, self.wristJnt, self.handcupJnt)
The issue is that in the __init__() call of the Class_UI, you have defined the wrong class call for the actual function gen_arm_joints(self), it should be: self.Joints = Gen_Joints(), seems like you have different import classNames but in the code you have called the class as Gen_Joints. You can't pass in two self classes references i.e the error traceback.
You will have to fix the import class to import Gen_Joints.
#FishingCode
Look out what I tried based on what you told me :
import sys
sys.path.append('G:\\3D2\\Script\\Auto_Rig')
import Class_Joints
import Class_Arms
import maya.cmds as mc
class Window_UI(object):
# Initializing global variables
def __init__(self):
# Getting acces to the different modules
self.Arms = Class_Arms.Arms_Rig()
self.Joints = Gen_Joints()
# Create Ui
self.create_UI()
# Creating the UI
def create_UI(self):
# Create window
self.UI = mc.window(title='Auto-Rig Tool', w=(300), h=(350))
# Main layout
self.mainLayout = mc.menuBarLayout()
# Create Joints Button
self.createJointsButton = mc.button(label='Create Joints', command=self.Joints.gen_arms_joints)
#show window
Window_UI()
mc.showWindow()
It's exactly what I have on Visual Studio Code
import maya.cmds as mc
class Gen_Joints:
# Creating arm Jnts and the list of it
def gen_arms_joints(self):
self.shoulderJnt = mc.joint(absolute=True, position=[5,8,0], n='L_Shoulder_Jnt')
self.elbowJnt = mc.joint(absolute=True, position=[10,8,-1.5], n='L_Elbow_Jnt')
self.wristJnt = mc.joint(absolute=True, position=[15,8,0], n='L_Wrist_Jnt')
self.handcupJnt = mc.joint(absolute=True, position=[18,8,0], n='L_HandCup_Jnt')
self.jntList = mc.ls(self.shoulderJnt, self.elbowJnt, self.wristJnt, self.handcupJnt)
VS Code tells me Undefined variable 'Gen_Joints'
And within maya I get # Error: NameError: file <maya console> line 16: global name 'Gen_Joints' is not defined #
mc.button passes on an extra boolean value to the method, so since that's not defined in gen_arms_joints it throws that error and says it's the wrong number of arguments.
So simply add an extra parameter and it'll fix it:
def gen_arms_joints(self, extra_param):
Or better yet use *args instead to be a bit more generic:
def gen_arms_joints(self, *args):
It's honestly kind of sneaky because it's not really stated in the documentation, but you can see it being used in the example at the bottom of the page.

Kivy call function in other screen

So I'm working on a kivy project and also learning the language for it (I mean python) and I have this little program here. So there are some language button on my first screen but I also have text to change in the second page. How can I call an other class' function in a class, or should I use a different way to change the textes? Any tipp would be helpful :) thanks
class ScreenOne(Screen):
def d_language(self):
self.hellolabel.text='Hallo'
def fr_language(self):
self.hellolabel.text='Bonjour'
class ScreenTwo(Screen):
def d_languagetwo(self):
self.otherlabel.text='Zweite seite'
def fr_languagetwo(self):
self.otherlabel.text='Deuxième page'
You can use the screen manager to get to the other screen
def d_language(self):
self.hellolabel.text = 'Hallo'
#now change the other label
s2 = self.manager.get_screen('name of the other screen')
#or ...
#s2 = self.manager.screens[1] # will also work...
s2.otherlabel.text = 'Zweite seite'
#or ...
#s2.d_languagetwo()
...

items of listwidgets in pyqt4 doesn't work properly

self.pushButton.clicked.connect(self.search)
def search(self):
import subprocess
keyword = str(unicode(self.lineEdit.text()))
subprocess.call(["some command"])
video_list = []
self.listWidget.clear()
video_ret = parse_vid(video_list)
self.listWidget.addItems(video_ret)
self.listWidget.itemDoubleClicked.connect(self.surf)
#######################################################################
def surf(self):
print "hello"
This code work fine for first time. But if I click pushbutton for the second time item click in listwidget gives me two execution of surf method. If I click pushbutton third time item click in listwidget execute surf method three time. Can any one help me with this weird problem??
A signal can be connected to multiple slots, in your case whenever you use the search function you are adding a new slot, it is better to add it once.
self.listWidget.itemDoubleClicked.connect(self.surf)
self.pushButton.clicked.connect(self.search)
def search(self):
import subprocess
keyword = str(unicode(self.lineEdit.text()))
subprocess.call(["some command"])
video_list = []
self.listWidget.clear()
video_ret = parse_vid(video_list)
self.listWidget.addItems(video_ret)
#######################################################################
def surf(self):
print("hello")

api: how to get selected text from object sublime.Selection

How to get selected text in sublime text 3 plugin:
import sublime, sublime_plugin
class plugin_window__go_to_relative_plugin__Command(sublime_plugin.WindowCommand):
def run(self):
window = self.window
view = window.active_view()
sel = view.sel()
sublime.status_message("selection: "+sel)
My code throws error:
sublime.status_message("selection: "+sel)
TypeError: Can't convert 'Selection' object to str implicitly
view.sel() returns sublime.Selection object. But I don't know how to get selected text from there.
This plugin must work as following:
When I call it on view...
... it should set text "dow = self.w" to variable sel
When I do str(sel) it returns <sublime.Selection object at 0x1047fd8d0>
Docs are not very clear for me.
My understanding of what the documentation means is this:
It sounds like the sel() method of a sublime.View object returns a sublime.Selection object, which is a container of regions—so you should be able to iterate over its contents (the regions it contains) or index into them using the [] operation.
You can get the text associated with each sublime.Region in a Selectionby calling the substr(region) method of a sublime.View object. This makes sense as this editor allows there to be multiple simultaneous selections—one of its cooler features, IMHO.
Hope this helps.
In case of single selection:
import sublime, sublime_plugin
class selection_plugin__Command(sublime_plugin.WindowCommand):
def run(self):
print('selection_plugin__ called')
window = self.window
view = window.active_view()
sel = view.sel()
region1 = sel[0]
selectionText = view.substr(region1)
print(selectionText)
Use it in console and then append in python
view.substr((view.sel())[0])

How can I create a status bar item with Cocoa and Python (PyObjC)?

I have created a brand new project in XCode and have the following in my AppDelegate.py file:
from Foundation import *
from AppKit import *
class MyApplicationAppDelegate(NSObject):
def applicationDidFinishLaunching_(self, sender):
NSLog("Application did finish launching.")
statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength)
statusItem.setTitle_(u"12%")
statusItem.setHighlightMode_(TRUE)
statusItem.setEnabled_(TRUE)
However, when I launch the application no status bar item shows up. All the other code in main.py and main.m is default.
The above usage of .retain() is required because the statusItem is being destroyed upon return from the applicationDidFinishLaunching() method. Bind that variable as a field in instances of MyApplicationAppDelegate using self.statusItem instead.
Here is a modified example that does not require a .xib / etc...
from Foundation import *
from AppKit import *
from PyObjCTools import AppHelper
start_time = NSDate.date()
class MyApplicationAppDelegate(NSObject):
state = 'idle'
def applicationDidFinishLaunching_(self, sender):
NSLog("Application did finish launching.")
self.statusItem = NSStatusBar.systemStatusBar().statusItemWithLength_(NSVariableStatusItemLength)
self.statusItem.setTitle_(u"Hello World")
self.statusItem.setHighlightMode_(TRUE)
self.statusItem.setEnabled_(TRUE)
# Get the timer going
self.timer = NSTimer.alloc().initWithFireDate_interval_target_selector_userInfo_repeats_(start_time, 5.0, self, 'tick:', None, True)
NSRunLoop.currentRunLoop().addTimer_forMode_(self.timer, NSDefaultRunLoopMode)
self.timer.fire()
def sync_(self, notification):
print "sync"
def tick_(self, notification):
print self.state
if __name__ == "__main__":
app = NSApplication.sharedApplication()
delegate = MyApplicationAppDelegate.alloc().init()
app.setDelegate_(delegate)
AppHelper.runEventLoop()
I had to do this to make it work:
Open MainMenu.xib. Make sure the class of the app delegate is MyApplicationAppDelegate. I'm not sure if you will have to do this, but I did. It was wrong and so the app delegate never got called in the first place.
Add statusItem.retain() because it gets autoreleased right away.

Categories

Resources