Putting a Command on a Menu
Updated 05 Apr 2018
|
Upper levels: - QuArK Information Base - 3. Advanced customization - 3.6. Plug-Ins - 3.6.1. Plugin Tutorial |
3.6.1.2. Putting a Command on a Menu |
[ | - - ]
A plugin needs to do four things:
And it should also register itself. So we'll do these five things in turn. |
Index |
Setting up |
tiglari - 05 Apr 2018 | [ Top ] |
What we'll be doing is making a replacement maptagside plugin. The real one is interconnected with some other plugins which we'll have to disable, & it would not be a good idea to mess with your regular QuArK installation, so you should make a second one, and in that installation, remove the files `plugins\mb2caulk' and `plugins\maptagside'. Since we're going to be making a series of new maptagside plugins, it might be convenient to call them maptagside0.py, maptagside01.py; you can disable the older ones and keep them from loading by renaming them `tagside0.py', etc (since plugins are only loaded by the mapeditor if their names begin with q- or map-, or mb2- for Q3 engine games). |
Importing |
tiglari - 05 Apr 2018 | [ Top ] |
What you need to import depends on what you're doing; what we'll need for the whole plugin is this: import quarkx import quarkpy.mapmenus import quarkpy.mapentities import quarkpy.qmenu import quarkpy.mapeditor import quarkpy.mapcommands from quarkpy.maputils import * |
Action |
tiglari - 05 Apr 2018 | [ Top ] |
To produce the action we want, we need this: def tagSideClick(m): quarkx.msgbox("This command does nothing", MT_INFORMATION, MB_OK) This defines a function `tagSideClick', which gets a parameter `m', which is the actual menu item that invoked the action. We don't use this here, but we will later on. The body of the function calls the `msgbox' function from the module `quarkx', which is imported in the first import statement. Note that this works a bit differently from say an #include in C; when we import a module, we can't just use the names of the functions in it, but have to `qualify' those names by putting the module name in front, separated by a period. This is to improve readability, at the expense of a a bit of typing on the part of the writer of the program; the name of the important function when it's used states where it came from, so the reader has a better chance of finding out what it does. We will soon see how to use unqualified imported names as well. As for the actual msgbox function, it produces little `message box' dialogs that you can respond to by pushing buttons; its first argument is the string to be displayed in the message box, the second a `type' which determines the graphic icons associated with the box, and third a flag that says that the messagebox has an OK button. Symbolic names for the useful values for these arguments are defined in the file quarkpy\qtils.py , under the heading `# quarkx.msgbox'. So you can look there to see what the possibilities are. But hey, we haven't imported this module, and the symbols aren't qualified anyway, so what's going on? What we have done is imported the module quarkpy.maputils, in a somewhat different way, in the last line of the import statement. from <module name%gt; import * means `import everything that's defined in the named module, and use it without qualification'. And furthermore, quarkpy.maputils, a general grab-bag of utility functions for the map editor, imports quarkpy.qeditor in this way, which itself does the same to quarkpy.qutils.py . So everything defined in all of these modules is available to our plugin, without qualifying the names. This is convenient for the writer, but can be confusing for the reader. Even more so because symbols defined in later imports will override definitions from earlier ones. So this import style should only be used for a limited number of widely used utility files, which people working on the program can be expected to learn about soon. One more thing with the import statements, what's the deal with the dots? Python modules are religiously identified as files, and folders are taken to be `super modules' containing sub-modules. So all of the files in quarkpy make up the quarkpy module, and to import them into a file outside of quarkpy you need the quarkpy. qualification. Inside quarkpy you don't, so the statement that maputils.py uses to import qeditor.py is just: from qeditor import * |
Putting it on a menu |
tiglari - 05 Apr 2018 | [ Top ] |
So now that we've got some code that does something, we need to install a menu item so the user can have it done: quarkpy.mapcommands.items.append(qmenu.item("&Do Nothing", TagSideClick)) def tagSideClick (m): quarkx.msgbox("This command does nothing", MT_INFORMATION, MB_OK) quarkpy.mapcommands.items.append(quarkpy.qmenu.item("&Do Nothing", tagSideClick)) def tagSideClick (m): quarkx.msgbox("This command does nothing", MT_INFORMATION, MB_OK) quarkpy.mapcommands.items.append(qmenu.item("&Do Nothing", tagSideClick)) And it remains to explain what this menu-item-adding line actually does. quarky.mapcommands is the module where the `commands' menu is defined. It creates a list-valued variable `items', and `append' is a built-in Python function for attaching something to a list. What we append to this list is an something created by the `item' function, defined in the module quarkpy.qmenu. We don't have to import this module because that job is already done by the qeditor.py module. This has among its import statements: import qmenu So when this is all typed out and saved into a file `maptagside.py' in in the plugins directory, you should be able to start up QuArK, fire up the map editor, find the `Do Nothing' command on the command menu, click on it, and see the resulting message box. If it doesn't work, possible explanations are:
If all else fails, the file maptagside0.py in plugin_examples.zip contains what is hopefully a working version of the code for this section. I'll also say a bit more about what goes on when modules are loaded. When a module is loaded, it is first `compiled' into a file with the same name and extension .pyc, which will load more quickly. If the current .py file is older than the corresponding .pyc file, the compilation stage is skipped, and the .pyc file is loaded straight in. So you can delete all the .pyc files if you want to, but it will slow things down the first time QuArK is run. |
Registering |
tiglari - 05 Apr 2018 | [ Top ] |
Finally, a properly dressed plugin should announce itself to QuArK, so it will be listed under Options|List of Plugins. This is done by including an Info statement, normally at the beginning of the file: Info = { "plug-in": "Side Tag & Glue", "desc": "Basic Side tagging and gluing to tagged side", "date": "1999", "author": "tiglari", "author e-mail": "tiglari@hexenworld.net", "quark": "Version 6" } So now we've got a proper plugin; next is to get it to do something useful. |
Copyright (c) 2022, GNU General Public License by The QuArK (Quake Army Knife) Community - https://quark.sourceforge.io/ |
[ Top - ] | -