Using Qt Designer for PyQt5, I promote a widget to be an instance of a custom widget. This works well.
Is there a way to instruct Qt Designer or pyuic5 to NOT add the import line for custom widget classes?
[Qt Designer does not let you leave the Header File line blank.]
The custom widget class is already defined and coded up in the same .py file as the rest of the main window code and top level code - the same file that imports the file generated by pyuic5 - and can't easily be broken out to a separate file for various reasons, basically because it wasn't written in a clean modular fashion. So, the import line added by pyuic5 is not needed and causes problems.
Snippets from the file generated by pyuic5:
...
self.tableView = CustomTableView(self.parentWidget)
...
from customTableView import CustomTableView
...
The "right" way to do things would be to refactor such that the custom widget class could be defined in its own file, so that it could be imported by the file created by pyuic5. But, that is problematic since the custom class calls methods from other classes also defined in the top level file, and also calls top level functions and variables defined in the top level file.
A few brute-force solutions come to mind: just comment out the line by hand, and/or modify the runtime code to comment out that line by hand before importing the generated file. Both of those are about as far from the "right" way to do things as you could get.
The real answer to this question is 'no, you cannot' from musicamante in comment to the original question.
So, here's a workaround that accomplishes the original intent: in Designer, change the header file for the promoted widget class to be the name of the top level code file (ending in .h instead of .py since it was originally written for C++) that imports the generated file and defines the custom widget class:
Then, the file generated by pyuic includes this line:
from topFile import CustomTableView
Since topFile.py imports the file generated by pyuic, this might seem like a circular import, but apparently it is fine and not circular, since the line above is only trying to (re)import one class, rather than (re)importing the entire file topFile.py which would be circular.
Related
(Noob alert!)
I want to add an SQLite component to a simple (one Java source file) app and would like to put it in a separate file. I was hoping to find something that would let me click a couple check boxes and creae the file using a template with the standard overrides and class declarations (e.g. ... MyClass extends SQLiteOpenHelper {...} and so on. Instead I can't even figure out how to add an empty .java file to the project. Google's Android Studio Tips 'n Tricks suggest navigating to the 'appropriate directory in the Project pane' and hit N. That gets me a dialogue that rejects my class name and seems to open a header file if I enter the name if the class I wish to extend (and without apparently adding anything to my project.)
I do not even see a way to add an existing file to the project. OK... I now see that if I create the .java file in the app directory (along side the MainActivity.java file) that Android Studio automatically includes it.
Is this Standard Operating Procedure? It leaves me feeling like I'm not leveraging the capabilities that Android Studio provides.
I'm using AS 0.5.2, openJDK 1.7.0
Thanks!`
If you're creating a new Java class from the Project pane, you don't need to add the ".java" to the name; you're specifying the name of the Java class, not the source file. It will figure out the filename automatically.
I would like to pass data such as navigation items or languages supported to the portal_normal.vm file so that it gets displayed on the portal.
I don't have a clue about how to do it. I've seen that in velocity files the data is passed in variables as follows:
<title>$the_title - $company_name</title>
I would like to do the same for navigation items and other data in my portal but I have no clue how.
Liferay's themes have a file called init.vm - this initializes quite a bit of the data. If you don't find it in your theme, it will be loaded from the _styled or _unstyled theme that you can find within the portal (or the portal source).
You can also look at the Java side of the equation: There's a class called VelocityVariablesImpl, this initializes "the other" variables in the context.
In addition, you can have a file named init_custom.vm in your custom theme, where you can add more initialization. This file is meant to be empty in default themes, but as it's included and evaluated, you can add your custom variables and initialize them in here.
Is it possible to create a layout file inside of a module ? How ?
For what:
I want to add a some kind of statistics hit counter for products, and I don't want to override the products class, as that is already done by some module I'm using. Thus I thought it would be best to have a custom module with a block that would be called by a layout statement.
Of course I could easily edit my private local.xml or make changes to another layout-xml in the layout folder of my theme, but I want this feature to be available in all themes (independent of any selected theme).
Some constraints:
All code in one single module
... so that it is theme independent
... so that the module can be shared with others without them having to change anything (like theme files), so that the install/load of my module would be enough
I would also accept different approaches for my statistics hit counter loading (using the same constraints)
Yes it is possible. Just create your layout xml file in the following path: /design/frontend/default/default/layout/yourlayout.xml(or whatever your theme name is), and add a proper statement in your modules etc/config.xml:
<config>
<frontend>
<layout>
<updates>
<yourmoduleshortname>
<file>yourlayout.xml</file>
<yourmoduleshortname>
</updates>
</layout>
</frontend>
</config>
This sample is for frontend user, but adminhtml layouts can be updated in a similar manner. If something doesn't work, be sure to check if your layout is in the proper theme/package directory.
Edit:
Second approach:
You can use a controller of your own, which will extend the core functionality (one of the catalog controllers) - just rewrite it (or just product view action). Inside its action method add something like this:
$thiss->getLayout()->createBlock('namespacename/block','layout-block-name',
array('template' => 'relativepathtotemplate.phtml'));
$this->getLayout()->getBlock('content')->append($block);
run-original-parent-code();
Third approach:
Similar to the previous one, but you can use some event observer, and try Mage::getSingleton('core/layout'), and inject your block there. Not in all events the layout will be already available (try the post_dispatch family).
I don't really recommend the second and third approach, because if someone else wants to find where this 'magic' block comes from, it will most surely look int app/design/(...) directory. Finding it in your controller or model, may be very tricky...
If you don't want to display your statistic counter, you can also use events (like post_dispatch) to count the controller dispatches. Just create an observer attached to it, and store your data in the DB.
** New EDIT **
so what I'm trying to do is this.
I want the to add new form elements generated by my module on the product view of the following url
http://magento.example.com/catalog/product/view/id/46
ultimately these elements will be determined to show up by a related table in my module
I expected that if I extended Mage_Catalog_Block_Product_View in my module as shown below I would be able to create a block in the product form that would contain such form fields, only if he are in the related table in my module
so I created a test.phtml file in
app/design/frontend/default/default/templates/<module>/test.phtml
then as you can see in my the View.php file described bellow I built the block and displayed it in the product view.
It did appear but 5 times too many. from the answers below this is normal so that answers the question as to why the it shows up five times but leaves the question what is the proper way to proceecd since this plan is not going to work
** End New Edit **
in my module I call _prepareLayout() and it does this 5 times when i pull up the page
here's my code
in
/app/code/local/Namespace/Module/Product/Veiw.php
class <Namespace>_<module>_Block_Product_View extends Mage_Catalog_Block_Product_View {
protected function _toHtml() {
return parent::_toHtml();
}
public function _prepareLayout() {
$block = $this->getLayout()->createBlock(
'Mage_Core_Block_Template',
'my_block_name_here',
array('template' => '<module>/test.phtml')
);
if ($block){
$this->getLayout()->getBlock('content')->insert($block)->toHtml();
}else{
echo "no block";
}
return parent::_prepareLayout();
}
}
NOTE:
I just noticed this also takes away the price availability qty and add to cart button. which is also a problem
EDIT
First I want to thank you all for your answers. Second i want to give you more context
the reason for choosing to do this in the module is that I don't want the block to show up on every product . What i have is a table of what I'll call custom options containing properties of the product sort of like hair color height weight etc and depending on what set of properties are attached to the product (if any) will depend on what html content will show up on the page.
so in one case it my get a drop down menu and in another case it may get an input box. the other very important piece is that this must be setup so that I can give the end result out as a module that can be installed and not worrry that it won't show up if someone upgrades there magento
that said does it still make sense to do this all in the xml file ?
It seems to me that your code is overriding a core Magento module in order to achieve what could be easily done in the layout xml configuration. I would strongly recommend the follwing:
Use the built-in configuration mechanisms (e.g. layout xml - read Alan's excellent tutorial here) instead of writing code whenever possible.
Don't override the core code
if you must change the behaviour of the core code, use an Observer rather than Rewrite/Override
if you absolutely must Override, always call parent::whatever()
For example, if you create a <module>.xml layout file in your theme (app/design/frontend/default/<theme>/layout), you could use the following code:
<catalog_product_view>
<reference name="content">
<block type="module/block" name"my_block_name_here" template="module/test.phtml"/>
</reference>
</catalog_product_view>
You would then need to use a getChildHtml('my_block_name_here'); call within your phtml to position the block.
So unless there is other functionality happening inside your _prepareLayout, there's no need to override the core, or even to override the default catalog.xml.
EDIT (small edit above)
So now in your Block (I would recommend that you call it Namespace_Module_Block_Product_Customattributes or something like that), you are not overriding the core Product_View block, but merely processing your logic for what html widgets to use to render your custom attributes. Leave the rest of the tier prices, add to cart, other generic product block code, etc to Magento to work out.
If you are worried about the upgrade path for your module's users, you should definitely NOT be overriding core code. Use the configuration approach and very selectively introduce code that "plays nice" with the system rather than try to boss it around with overrides.
I took a look at a stock Magento install of CE 1.4.1, and unmodified the _prepareLayout method is called six times when loading the URL
http://magento.example.com/catalog/product/view/id/46
That's because the class is instantiated six times. So that's the correct behavior.
As for the vanishing element, I can'y say for sure, but your override to _prepareLayout doesn't appear to either
Do the same things as Mage_Catalog_Block_Product_View::_prepareLayout
Call parent::_prepareLayout();
When you override a class in a Magento you're replacing an existing class with your own. If you change a method, you're responsible for that old code being run.
It's not clear what you're trying to accomplish here. You should consider breaking your problem down into smaller problems, and then posting one (or more) "I tried X, expected Y, and got Z" type questions. As written no one's going to be able to answer your question.
I created a dialog and then created a class linked to it using the wizard. Somehow VC++ has forgotten this and now wants me to create a class whenever I double-click on a control in the editor to create a handler.
Are these mappings stored in a file I can edit, or does VC++ try to deduce this and I'm stuck with it?
In the header file for your dialog you should have a line like:
enum { IDD = IDD_ABOUTBOX_DLGTEST };
This specifies the resource ID for your dialog. Have you changed the ID for your dialog in the dialog Properties? Either change it back, or change the enum in the header file.
Note, any change might not get picked up by the wizard until you've done a re-compile.
As well as njplumridge's answer, also check that you have the right #include "projectname.h" file in all your classes.
You can sometimes have problems with MFC tools mapping if you change the name of the project but leave the projectname.h file unchanged.
But there's no extra mapping file to worry about, it's all inferred from the source code.