I can't find classes/attribute on matplotlib documents - python

From the code below, all I want to know is what is the window used for?
plt.ion()
figManager = plt.get_current_fig_manager()
figManager.window.showMaximized()
I went to the matplotlib documentation, searched for get_current_fig_manager() and it retured FigureManagerBase. I then looked at FigureMangerBase, and there's no window attribute, methods, super class is object.

In case you are using the Qt5Agg backend and look at the repr of the figManager.window, it is a matplotlib.backends.backend_qt5.MainWindow object.
Digging into the MPL code, you can find it is just a wrapper object for the QtWidgets.QMainWindow object. Code found on github:
class MainWindow(QtWidgets.QMainWindow):
closing = QtCore.Signal()
def closeEvent(self, event):
self.closing.emit()
QtWidgets.QMainWindow.closeEvent(self, event)
It looks like it just gets tacked on as an undocumented attribute to the FigureManagerBase object as a way to reference the open Qt window. This allows the user to access the Qt windows when in interactive mode without having to import Qt.
Probably should be documented. You can always put in an issue.

Related

Maya Python: Button always at the center of the window

I'm starting experimenting with Maya python, and I'm trying to do some UI.
I came across to a really strange problem, I can't get a button to stay in the center of the windows.
I've tried different things but nothing seems to work, here is the code:
import maya.cmds as cmds
cmds.window( width=200 )
WS = mc.workspaceControl("dockName", retain = False, floating = True,mw=80)
submit_widget = cmds.rowLayout(numberOfColumns=1, p=WS)
cmds.button( label='Submit Job',width=130,align='center', p=submit_widget)
cmds.showWindow()
this is a simple version but still, I can't get it to work.
can someone help me?
I honestly don't know the answer as anytime I have to dig into Maya's native UI stuff it makes me question my own life.
So I know it's not exactly what you're asking for, but I'll opt with this: Use PySide instead. At first glance it might make you go "woah, that's way too hard", but it's also a million times better (and actually easier). It's much more powerful, flexible, has great documentation, and also used outside of Maya (so actually useful to learn). Maya's own interface uses the same framework, so you can even edit it with PySide once you're more comfortable with it.
Here's a bare-bones example to create a centered button in a window:
# Import PySide libraries.
from PySide2 import QtCore
from PySide2 import QtWidgets
class MyWindow(QtWidgets.QWidget): # Create a class for our window, which inherits from `QWidget`
def __init__(self, parent=None): # The class's constructor.
super(MyWindow, self).__init__(parent) # Initialize its `QWidget` constructor method.
self.my_button = QtWidgets.QPushButton("My button!") # Create a button!
self.my_layout = QtWidgets.QVBoxLayout() # Create a vertical layout!
self.my_layout.setAlignment(QtCore.Qt.AlignCenter) # Center the horizontal alignment.
self.my_layout.addWidget(self.my_button) # Add the button to the layout.
self.setLayout(self.my_layout) # Make the window use this layout.
self.resize(300, 300) # Resize the window so it's not tiny.
my_window_instance = MyWindow() # Create an instance of our window class.
my_window_instance.show() # Show it!
Not too bad, right?

Overriding/Reimplementing Slots in PySide

I have almost the exact same question as the one found here:
Override shouldInterruptJavaScript in QWebPage with PySide
In my case though I want to override the copy and paste slots on QLineEdit
import sys
from PySide import QtGui, QtCore
class myLineEdit(QtGui.QLineEdit):
# FIXME: This is not working, the slot is not overriden!
#QtCore.Slot()
def copy(self):
print 'overridden copy event'
App.clipboard().setText('customized text')
return False
#QtCore.Slot()
def paste(self):
print 'overridden paste event'
self.setText('customized text')
return False
if __name__ == "__main__":
App = QtGui.QApplication(sys.argv)
Widget = myLineEdit()
Widget.show()
cmenu = Widget.createStandardContextMenu()
sys.exit(App.exec_())
I'm using Python 2.7.3, with PySide 1.2.2
I don't know if these methods are even supposed to be override-able, but I can't find any documentation that says they shouldn't be.
I also found this page
http://qt-project.org/faq/answer/is_it_possible_to_reimplement_non-virtual_slots
The page explains how certain kinds of slots get pointers set to them by functions that get called when the object is initialized (or something along those lines, I'm not as familiar with the C++).
Following this logic I added the createStandardContextMenu() call above in the hopes that it would reinitialize the slots for at least the context menu, but no luck.
Am I doing something wrong? Or should I try filing a bug report?
You cannot override QLineEdit.copy or QLineEdit.paste in such a way that they will be called internally by Qt.
In general, you can only usefully override or reimplement Qt functions that are defined as being virtual. The Qt Docs will always specify whether this is the case, and for QLineEdit, there are no public slots that are defined in that way.
There is also no easy workaround. There are a lot of different ways in which copy and paste operations (or their equivalents) can be invoked, such as keyboard shortcuts, context menu, drag and drop, etc. It can be done: but it's a lot of work to get complete control over all these sorts of operations. So you need to think carefully about what you're trying to achieve before deciding how to proceed.

Changing the font in Enthought TraitsUI TextEditor

I would like to change the font in a TextEditor in TraitsUI view. How can I do this?
I read the (excellent) documentation, the API reference docs and asked Google for an answer, but could not find one.
Platform- and toolkit-independence is not a requirement for my application. I work on Windows and use the wx toolkit.
After digging into the source code and some experimenting, I came up with the following solution. To me, this seems to be too complicated (I have to subclass two classes!) to be the simplest or intended way to do this.
If there is a better solution, I would be glad to learn about it.
import wx
from traitsui.wx.text_editor import CustomEditor
from traitsui.editors.text_editor import ToolkitEditorFactory
class _MyTextEditor(CustomEditor):
def init(self, parent):
CustomEditor.init(self, parent)
font = wx.Font(10, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
self.control.SetFont(font)
class MyTextEditor(ToolkitEditorFactory):
klass = _MyTextEditor
def _get_custom_editor_class(self):
return _MyTextEditor
def _get_simple_editor_class(self):
return _MyTextEditor
if __name__ == "__main__":
from traitsui.api import View, Item
from traits.api import Str, HasTraits
class MyTestcase(HasTraits):
a_string = Str()
traits_view = View(Item('a_string', editor=MyTextEditor()))
w = MyTestcase()
w.configure_traits()
I think Traits uses Qt. So to change the font size, use the style_sheet argument. See example below
Item('a_string', style_sheet='*{font-size:24px}')
If you want to apply multiple font options, separate with a semicolon like this:
Item('a_string', style_sheet='*{font-size:24px; font-style:italic}')
For all of Qt stylesheet options that you can apply, look at
Qt Style Sheets Reference

PyQt: updating GUI from a callback

Using Python3 and PyQt4 I have a function (run) that takes as an input a callable to provide status updates.
class Windows(QtGui.QWidget):
# Creates a widget containing:
# - a QLineEdit (status_widget)
# - a button, connected to on_run_clicked
def on_run_clicked(self):
def update(text):
self.widget.setText(text)
threading.Thread(target=run, args=(update, )).start()
This works ok (i.e. the text updates are displayed properly in the widget). However, when I replace QLineEdit by QTextEdit and use the append method to add text, I get:
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
It still works but point to the fact that I am doing something wrong, and I am not sure that I will keep working when more threads are active. Usually, I do this type of updates using signals and slots, but the run function is not PyQt specific. The questions are:
Why does it work without a warning for QLineEdit and not for
QTextEdit?
What is the right way to deal with a situation like this?
I don't know the specific reason why one class works and the other doesn't - nor do I really know the difference between using Python threading vs. Qt's threading...however, I can tell you that it is very tempremental if you don't set it up properly. Namely, you cannot (or at the very least, should not) modify GUI objects from a thread. Again, not sure the difference of a python vs. a Qt thread on that. But, the safe way to modify your interface from a GUI is by sending signals to your window...easiest way I know to do this is via the Qt threading.
class MyThread(QtCore.QThread):
updated = QtCore.pyqtSignal(str)
def run( self ):
# do some functionality
for i in range(10000):
self.updated.emit(str(i))
class Windows(QtGui.QWidget):
def __init__( self, parent = None ):
super(Windows, self).__init__(parent)
self._thread = MyThread(self)
self._thread.updated.connect(self.updateText)
# create a line edit and a button
self._button.clicked.connect(self._thread.start)
def updateText( self, text ):
self.widget.setText(text)

pyQT phonon player to fullscreen?

i was wondering how to set a phonon player to full screen?
im trying this codes.
if not self.ui.videoPlayer.isFullScreen():
self.ui.videoPlayer.enterFullScreen()
else:
self.ui.videoPlayer.exitFullScreen()
but i keep on getting this error message
TypeError: 'sip.methoddescriptor' object is not callable
the code above works is from a sample project. the original code was
def full(self):
if not self.videoWidget.isFullScreen():
self.videoWidget.enterFullScreen()
else:
self.videoWidget.exitFullScreen()
im recreating it in PyQT and it seems hard for me.
can anyone please guide me on what im missing(having a hunch about it)
or what im doing wrong?
A VideoPlayer is not the same thing as a VideoWidget.
VideoPlayer is a subclass of QWidget, so it will have an isFullScreen method - but it won't have the methods enterFullScreen and exitFullScreen, which belong to the VideoWidget class.
However, the VideoPlayer class has a videoWidget method which returns the instance of the video widget it uses, so your code example should probably be changed to:
videoWidget = self.ui.videoPlayer.videoWidget()
if videoWidget.isFullScreen():
videoWidget.exitFullScreen()
else:
videoWidget.enterFullScreen()
EDIT
To provide a method for exiting fullscreen mode, set up a keyboard shortcut:
class MainWindow(QtGui.QMainWindow):
def __init__(self)
...
self.shortcutFull = QtGui.QShortcut(self)
self.shortcutFull.setKey(QtGui.QKeySequence('F11'))
self.shortcutFull.setContext(QtCore.Qt.ApplicationShortcut)
self.shortcutFull.activated.connect(self.handleFullScreen)
def handleFullScreen(self):
videoWidget = self.ui.videoPlayer.videoWidget()
if videoWidget.isFullScreen():
videoWidget.exitFullScreen()
else:
videoWidget.enterFullScreen()
I think the problem is your use of self.ui.videoPlayer.isFullScreen, it's probably returning True or False, which when you use self.ui.videoPlayer.isFullScreen() is really resolving down to 'False()'.
Oddly enough, the PyQT documentation doesn't even list 'isFullScreen' as part of the available, methods/properties. However the QWidget documentation does show isFullScreen as returning a boolean.
Instead, try this:
if not self.ui.videoPlayer.isFullScreen:
self.ui.videoPlayer.enterFullScreen()
else:
self.ui.videoPlayer.exitFullScreen()

Categories