I have trouble getting custom widgets to work in Glade. Let's say I have a custom widget consisting of a stack in a frame.
class FramedStack(Gtk.Misc):
def __init__(self):
self.frame = Gtk.Frame()
self.stack = Gtk.Stack()
self.frame.add(self.stack)
I can add this to the Glade catalogue and it works fine. But now I want to modify the widgets behaviour in Glade. But as soon as I define an adaptor
class FramedStackAdaptor():
def do_post_create(self, w, reason):
pass #something
and modify the line in the catalogue, so that Glade knows about the adaptor
<glade-widget-class title="FramedStack" name="FramedStack" adaptor="FramedStackAdaptor"/>
I get a GladeUI warning
GladeUI-WARNING **: Failed to get FramedStack's adaptor FramedStackAdaptor.
The class definition is in the same file as the definition of the custom widget. I am assuming that FramedStackAdaptor should inherit a Glade Adaptor class, but I can't figure out whether there are such classes. So my question is: How do I correctly define an adaptor for my custom widget?
class FramedStackAdaptor(Gladeui.WidgetAdaptor):
def post_create(w, reason):
pass #something
Should get you started
Related
Thank you all so much! I just started in Kotlin which probably should be called the K language (like C and F), and have found so many solutions here on this site...it's awesome!
I have an independent class file called AppTime.kt and it's declared in the AndroidManifest.xml file:
<application
android:name=".AppTime"
class AppTime : Application() {
fun burntToast(sMsg: String) {
Toast.makeText(this.applicationContext, "!", Toast.LENGTH_LONG).show()
}
}
It doesn't run when called anywhere from a Fragment class:
class FirstFragment : Fragment() {...
AppTime().burntToast()
I've tried every approach using parameters for the Toast following makeText(...
and then to call it from a Fragment with or without context or string parameters.
Is it the type of class I have?
Functions defined inside a class can only be called on an instance of that class, as you already found.
But you cannot simply instantiate an arbitrary Application and expect it to work. Android does a lot of behind-the-scenes setup of framework classes before they are usable. Any Application or Activity that you instantiate yourself is useless. You have to use the instances that are provided to you through the lifecycle of the Activities that get launched in your application.
If you want to call this function from your Fragment, you will have to get an instance of your application, which you can get from its associated Activity. Since the Activity class doesn't know about your specific subclass of Application, you must also cast the application to your specific subclass to be able to call its unique functions. You can get the Activity by using requireActivity().
(requireActivity().application as AppTime).burntToast()
How do I override a widget in order to provide some custom modifications to one of its property.
For example: Let's say I want to create my own Text widget which will convert whole text to uppercase. I'll do something like:
class MyOwnText extends Text {
MyOwnText(String data) : super(data.toUpperCase());
}
But with this approach, I can't use other properties of Text in my own widget, style, for example. For that, I'll have to add style property in my class constructor like this:
MyOwnText(String data, {TextStyle style}) : super(data.toUpperCase(), style: style);
But Text has got around 12-13 properties, and just to override one, I need to define all of those properties and then their assertion. I'm sure I may not be doing something right. Can anyone please help?
Note: Neither I want to use extension methods nor some client side code. MyOwnText should be a Text.
I get what you wanted to achieve, but I do not recommend to do this.
Why?? - Because most of the class has private variable and they have their separate getter and setter which are expose to the outer front of the class.
Again, If you wanted to for design and func. then you should not extend the widget. Instead you can directly use those in your build method
Why?? - You can't inherit more than one class(Mixin is other way around here)
So ultimately you need to assign properties directly or you could use spread operator
Here is a screenshot of the Blueprint editor for my CharacterSelectMenuWidget blueprint. This Blueprint's parent is a C++ class that extends a UUSerWidget.
Blueprint Editor Screenshot
The TeamSelectorWidget and RoleSelectorWidget are both Blueprints of type BinaryOptionSelectorWidget. That Blueprint's parent is a C++ class called UBinaryOptionSelectorWidget. I want to grab a reference to the TeamSelectorWidget and the RoleSelectorWidget that are children widgets of this blueprint's canvas inside the C++ class. I've tried the following, but this does not work
UBinaryOptionSelectorWidget TeamSelectWidget = Cast<UBinaryOptionSelectorWidget>(GetWidgetFromName(FName("TeamSelectorWidget")));
I may have the class casting wrong, though I'd expect to see some sort of error message if that were true. I can't use the Visual Studio debugger to evaluate the expression and debug that way, because it complains about the constructor for FName() (is that a known issue).
If anyone has an idea of how to access these variables, please let me know.
Is it possible to dynamically create objects or modify them on run-time ?for example,on button click,another button created or change number of lines of a road?
When I write this code for a button Action,in run-time
road123.setBackwardLanesCount(3);
I get error below:
root:
road123: Markup element is already initiated and cannot be modified.Please use constructor without arguments,perform setup and finally call initialize() .function
You'll get that error with any object you attempt to create at runtime using a parameterized constructor. If you create the object with a simple constructor (just "()") and then set all of the parameters individually, you won't run into that issue. Check the Anylogic API for specific information about the object you are using, because some require you to call .initiliaze() on that object after setting all of it's parameters if you created it using a simple constructor. Furthermore, if you want to add the object to the screen at runtime you'll need to add this code to the function that creates it:
#Override
public void onDraw( Panel panel, Graphics2D graphics) {
obj.drawModel(panel, graphics, true);
}
where obj is replaced with the name of the object you created dynamically.
Some programmers create Window classes:
class PyApp(gtk.Window):
...
I've defined my window with Glade and then i can get it with:
xmlTree.get_widget('window')
Is there a way to use this object as class and extends it? I want to handle it as other programmers do but using my defined window. I don't want to get a class and a window property.
Thank you.
The simplest way I can think of is to use Glade to construct an Alignment laid out with widgets as you would want your window to look. Your class can then be something like:
class PyApp(gtk.Window):
def __init__(self, filename, widget_name):
# Use builder to open filename
...
# and then add the alignment widget:
self.add(builder.get_object(widget_name))