I'm new to PyopenGL and i'm currently working on a code originally based on the pyggel library, but now I'd like to add some features from GLUT (menu & text) and I'm not really sure how I should join both (if possible).
In GLUT, running glutMainLoop() is required, but on the other hand I have this run() routine:
def run(self):
while 1:
self.clock.tick(60)
self.getInput()
self.processInput()
pyggel.view.clear_screen()
self.mouse_over_object = self.scene.render(self.camera)
pyggel.view.refresh_screen()
#glutMainLoop()
Putting the GLUT routine inside my run() doesn't work (it crashes when it gets to the glutMainLoop).
So, how can I join both loops? Can I? I'm guessing that's what I need to make both things work.
Thanks in advance!
You likely are not going to find this easy to do. Pyggel is based on the Pygame GUI framework, while GLUT is its own GUI framework. You may be able to get text-rendering working, as under the covers GLUT is just doing regular OpenGL for that, but the menus are not going to easily work under Pyggel.
Pyggel has both text-rendering and a GUI framework that includes menus, frames, buttons, labels, etc. You likely want to use that if you're using Pyggel in your project there is an example of GUI usage here:
http://code.google.com/p/pyggel/source/browse/trunk/examples_and_tutorials/tut8-gui.py
I'm having some trouble using ILNumerics in LinqPad. I have the following code in LinqPad:
void Main()
{
var scene = new ILScene {
new ILPlotCube(twoDMode: false) {
new ILSurface(ILSpecialData.sincf(40, 60, 2.5f)) {
Wireframe = { Color = Color.FromArgb(50, Color.LightGray) },
Colormap = Colormaps.Jet
}
}
};
scene.First<ILPlotCube>().Rotation = Matrix4.Rotation(new Vector3(1f, 0.23f, 1f), 0.7f);
scene.Camera.Add(new ILSphere());
var panel = new ILPanel { Scene = scene };
PanelManager.DisplayControl(panel);
}
This code results in a big blue circle (with the text "ILNumerics ILPanel (OpenGL)" in the center) in the "custom" linqpad tab. The "Results" tab in linqpad contains the following text:
Determining Design Mode...
Entry Assembly: (null)
CurrentTypeAssembly: ILNumerics32, Version=3.1.0.0, Culture=neutral, PublicKeyToken=null
Loaded Assemblies:
Design Mode: True
Questions:
Is possible render this as a WPF element instead of a WinForms control? (I guess this will render the plot successfully)
Alternatively; is it possible to "trick" the ILPanel to think it isn't being rendered in design mode?
1) ILNumerics targets Winforms only. But you may try to use a WPF WindowsFormsHost container? I don't have any experience with it and do not expect an improvement for your situation though.
2) The way ILNumerics is checking DesignMode right now: if the executing assembly (ILNumerics.dll) is not in the list of references of the entry assembly (LinqPad), DesignMode is considered. Therefore, I can see 2 "tricks":
Make LinqPad depend on ILNumerics. Probably not the best solution though.
Patch ILNumerics: Alter the helper method refered to by Joe Albahari to return false instead.
The second "trick" may could lead us to a future solution. I don't know, if the "normal" DesignMode property does work in conjunction with LinqPad either? Maybe we could combine the existing method with a settings switch for all uncommon cases.
Yes, you can render WPF controls in LINQPad - either by using PanelManager.DisplayWpfElement (or just by dumping it).
I don't think it will help you though, because ILNumerics uses Windows Forms only. It doesn't reference any of the WPF libraries.
I don't know whether it's possible to trick ILNumerics into thinking it's not in design mode. Take a look in Reflector at ILNumerics.Drawing.ILHelper.IsDesignMode. It's doing something dodgy with referenced assemblies. I don't know why they don't just check the control's DesignMode property - that's the normal way of doing it.
I'm using matplotlib housed in a wxPython panel to do some heavy duty plotting. My issues comes when using native panning tool - it's appears as though matplotlib tries to constantly redraw the canvas as you drag the pan handle around. With the amount of data I'm plotting this is getting really choppy (already optimized with Collections for data etc)
In terms of performance I think it would be much preferable for the canvas to just draw once when the mouse is released at the end of a pan. I realise this will mean I have to extend the WxAgg NavigationToolbar2 class with my own, but I'm wondering if anyone has attempted something similar to this and can advise me on which functions to override?
many thanks
I've spent a lot of time making modification on the matplotlib backends, I've never done this specific change, but I can show you one line of code to comment out that will stop the dynamic updating:
I presume you are using the WxAgg backend, if this is the case, open this file: C:\Python27\Lib\site-packages\matplotlib\backends\backend_wx.py
And comment out the line indicated here:
def dynamic_update(self):
d = self._idle
self._idle = False
if d:
#self.canvas.draw() #<--- Comment out to stop the redrawing during the Pan/Zoom
self._idle = True
I tested this and it seems to nicely solve your issue. I did some quick digging and I didn't see any other functions calling this procedure so you might even be able to just change it to:
def dynamic_update(self):
pass
...Which is the same code you'll find in the base NavigationToolbar2 class
(And of course, if you're happy with this change you can do a little more work to make your own custom backend with this kind of modification. Just to make sure you don't lose the change when upgrading matplotlib)
I am using Qt5 beta and trying to embed a QWidget-based object into QML. The goal is to use QML as much as possible, and only use QWidget objects where QML does not do what I need. I found a link explaining how to do this for Qt4.7, but I have not found any information explaining how to do this in Qt5.
http://doc.qt.digia.com/4.7/declarative-cppextensions-qwidgets.html
The same example is also available in the Qt5 examples folder under:
examples\qtquick1\declarative\cppextensions\qwidgets
Unfortunately, this example uses QtQuick 1, rather than QtQuick 2, and I would like to use the new features of Qt5. I actually want to embed a qwt widget, but as a first step I would be happy to embed any simple QWidget-based object.
Can anybody help me get the example working under Qt5 / QtQuick 2 ?
Qt Quick 2 uses a scene graph for efficient rendering on the GPU. Unfortunately this makes it impossible to embed classic widgets into the scene. The old approach to embed such widgets with the help of QGraphicsProxyWidget works only with Qt Quick 1, because internally it uses a QGraphicsView for all the heavy lifting and QGraphicsProxyWidget is meant to be used with it.
As of now there are no plans to enable embedding classic QWidgets into the scene graph I know of. I think this is rather unlikely to change, because the concepts of QPainter, the painting framework used for the classic widgets, and the new scene graph doesn't play well with each other.
There some efforts to develop new widgets sets specifically tailored for the needs of QML, but none of them are as powerful and mature as the classic widgets. The most prominent ones are the QML Quick Controls, bundled with Qt since version 5.1.
If you really depend on QWT my advice would be to stick with Qt Quick 1.1 for now. It's still bundled with Qt 5, probably for cases like yours. That way you won't take advantage of the new scene graph, though.
You can embed QWidget to QML by using QQuickPaintedItem class:
http://doc.qt.io/qt-5/qquickpainteditem.html
Qt5 has an example:
http://doc.qt.io/qt-5/qtquick-customitems-painteditem-example.html
You should implement an inherent of QQuickPaintedItem with private widget attribute, that you want to embed. Provide paint method, that just render the QtWidget and provide mouse and other event transmitting from inherit of QQuickPaintedItem to embed QtWidget.
There's also QSG (Qt scene graph API), but my experience with that thing wasn't smooth. I believe the clue in multithreading (performing rendering in the different thread (not the Qt GUI thread one, however on Windows that's not true and all is done in main GUI thread).
I've implemented embedding of QCustomPlot, here's link: github.com/mosolovsa/qmlplot
What could be done is to render the widget to an image and upload as texture.For interaction someone needs to forward events like mouseClick or keyPressed from the sceneGraph, translate to widget coordinates, pass on, render and upload texture again. Just an idea :)
The recommended approach is to stay with a QWidget based application and embed the QML parts using QWidget::createWindowContainer.
Further to Julien's answer - a simple way to achieve this is to use QQuickWidget to display the QML scene, and then add a regular QWidget as a child of the QQuickWidget. You can also add a simple intermediate QObject to anchor the QWidget to an item in the scene.
E.g.:
In main.qml:
Item {
... // layouts, extra items, what have you
Item
{
objectName: "layoutItem"
anchors.fill: parent
}
... // more layouts, extra items, etc.
}
widgetanchor.h:
class WidgetAnchor: public QObject
{
ptr<QWidget> _pWidget;
QPointer<QQuickItem> _pQuickItem;
public:
WidgetAnchor(QWidget* pWidget, QQuickItem* pItem)
: QObject(pWidget), _pWidget(pWidget), _pQuickItem(pItem)
{
connect(_pQuickItem, &QQuickItem::xChanged, this, &WidgetAnchor::updateGeometry);
connect(_pQuickItem, &QQuickItem::yChanged, this, &WidgetAnchor::updateGeometry);
connect(_pQuickItem, &QQuickItem::widthChanged, this, &WidgetAnchor::updateGeometry);
connect(_pQuickItem, &QQuickItem::heightChanged, this, &WidgetAnchor::updateGeometry);
updateGeometry();
}
private:
void updateGeometry()
{
if (_pQuickItem)
{
QRectF r = _pQuickItem->mapRectToItem(0, QRectF(_pQuickItem->x(), _pQuickItem->y(), _pQuickItem->width(), _pQuickItem->height()));
_pWidget->setGeometry(r.toRect());
}
}
};
In main.cpp:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
auto pqw = new QQuickWidget;
pqw->setSource(QUrl::fromLocalFile("main.qml"));
pqw->setResizeMode(QQuickWidget::SizeRootObjectToView);
pqw->setAttribute(Qt::WA_DeleteOnClose);
auto pOwt = new MyWidget(pqw);
if (auto pOverlayItem = pqw->rootObject()->findChild<QQuickItem*>("overlayItem"))
new WidgetAnchor(pOwt, pOverlayItem);
pqw->show();
return app.exec();
}
The documentation states that using QQuickWidget has advantages over QQuickView and QWidget::createWindowContainer, such as no restrictions on stacking order, but has a 'minor performance hit'.
Hope that helps.
I need to add at run-time component of the PictureBox.
There will be a few to several. How can I do it?
Programmers writing based on the Compact Framework 3.5.
You would do it the same way that all controls are added. In general it looks like this:
var newControl = new Control(); // or new PictureBox
// initialize properties like size, position, etc
myForm.Controls.Add(newControl);
A good way to see how this is done for different controls is to look at the designer-created conde for InitializeComponents, as it creates all of the controls and layout done in the designers at run time.