QApplication Font Color - python

I'm writing a PyQt systemtray script. It simply a switch for system services. I'm adding QActions to QMenu via this code, my purpose is showing running services green and stopped services red:
....
for service, started in s.services.items():
action = self.menu.addAction(service)
if started: #It is my purpose, but obviously it doesn't work
action.setFontColor((0, 255, 0))
else:
action.setFontColor((255, 0, 0))
action.triggered.connect(functools.partial(self.service_clicked, service))
....
The problem is, QAction's don't have a setFontColor method :). It has a setFont method but I couldn't see a color related method in QFont documentation. And it doesn't support rich-text formatting.
I found a possible solution here, but it seems so much work for this simple operation.
Can anybody suggest me a simplier way?

The only simpler way I can see is to make your QActions checkable (and define for instance that "service is active" should check the item), and then play with Qt style sheets to get your desired effect.
Examples of styling menu items can be found here: Qt Style Sheets - Customizing QMenu

Not exactly what you want, but you could change the icon associated with the QAction to e.g. a red or green dot very simply : so the menu text wouldn't change colour but the dot would.
....
for service, started in s.services.items():
action = self.menu.addAction(service)
if started: #It is my purpose, but obviously it doesn't work
action.setIcon(QIcon(":/greendot.png"))
else:
action.setIcon(QIcon(":/reddot.png"))
action.triggered.connect(functools.partial(self.service_clicked, service))
....

Related

Changing background color (bgc) of windows in Maya?

I worked somewhere in the past where since we had multiple sessions of Maya open, the background color could be randomly changed so when you switched from a session quickly it was easy to sort out which window belonged to what Maya session.
And so far, I can change the bgc of the main UI by using:
window -e bgc 0.5 0.5 0.5 $gMainWindow;
After searching for other global variables, I found $AllWindows, $CommandWindow, among others since the docs state that 'bgc' is a windows only flag. I can not get any of the colors to change on any window besides the $gCommandWindow, which popped up and I do not recall seeing it before.
I'm hoping to at least change the Script Editor window in addition to MainWindow if anyone knows whether it's possible or not? It is not mission critical, but now I'm interested in seeing if it can be done.
Thanks!
Since Maya's interface is using Qt, you can use the power of PySide to tweak any widget you want. Usually the only tricky part is actually finding the proper widget to modify.
Here's how you can tweak the Script Editor to give it a yellow border:
import shiboken2
from maya import cmds
from maya import OpenMayaUI
from PySide2 import QtWidgets
panels = cmds.getPanel(scriptType="scriptEditorPanel") # Get all script editor panel names.
if panels: # Make sure one actually exists!
script_editor_ptr = OpenMayaUI.MQtUtil.findControl(panels[0]) # Grab its pointer with its internal name.
script_editor = shiboken2.wrapInstance(long(script_editor_ptr), QtWidgets.QWidget) # Convert pointer to a QtWidgets.QWidget
editor_win = script_editor.parent().parent().parent().parent() # Not very pretty but found that this was the best object to color with. Needed to traverse up its parents.
editor_win.setObjectName("scriptEditorFramePanel") # This object originally had no internal name, so let's set one.
editor_win.setStyleSheet("#scriptEditorFramePanel {border: 3px solid rgb(150, 150, 45);}") # Set its styleSheet with its internal name so that it doesn't effect any of its children.
OpenMayaUI.MQtUtil gives you the awesome ability to find any control by name, so as long as you know the name of the widget you want to modify, you can find it (tough part is finding it sometimes!). In this case I had to traverse up a few parents to find one that worked best to outline the whole window. You can fool around with this and color, let's say, only the text area. And since this is PySide's style sheets you can do whatever your heart desires, like effect the background color, the thickness of the outline, and so on.
Since we're only effecting the style sheet this also won't save with the preferences and will revert to what it was on a new session.
Hope that helps.

How to remove icon from QMessageBox in PyQt5?

I am trying to code a message box that just pops up and says something and has a single button to close it however as I only have a small amount of text in the box the icon/image to the left of it is huge and looks bad. I want to know how to remove it. I am also having trouble making custom message boxes. Tutorials say that this is how you make a custom message box:
box = QMessageBox()
box.setText('text')
box.addButton(QPushButton('Close', self))
box.exec_()
However this just closes my program and returns a 1. My current code uses the about method of QMessageBox():
box = QMessageBox().about(self, 'About', 'This is a test Program')
However this has that large icon in the text window and I can't seem to do anything else to the box as it just stops the program and returns 1 again
I am in desperate need of some decent PyQt documentation. I can't seem to find documentation on much at all unless it is in C++. For instance I cannot seem to find any information of options other than question and about for QmessageBox. So if someone could also show me where some proper documentation lives it would prevent me asking too many questions here
Rather than PyQt documentation, it is better to directly use Qt documentation. You only need to switch your language mindset from Python to C++, there and back. It is not that difficult. :) See e.g. http://doc.qt.io/qt-4.8/qmessagebox.html#addButton or http://doc.qt.io/qt-4.8/qmessagebox.html#about I think this is very detailed documentation, unrivaled by most other frameworks.
Note that there are three overrides of addButton(). From the documentation it seems that you either need to pass two arguments to box.addButton(QPushButton('Close', self), QMessageBox.RejectRole) (you forgot the role!) or better, you use the override which uses standard buttons, then you only pass one argument: box.addButton(QMessageBox.Close).
And one more tip for you: I also find it easier to debug my program with PySide than PyQt because unlike PyQt, PySide catches the exception, prints that to console and keeps running. While PyQt usually just silently crashes leaving you clueless. Most of the time, I am using shims Qt.py https://pypi.python.org/pypi/Qt.py/0.6.9 or qtpy https://pypi.python.org/pypi/QtPy to be able to switch from PyQt to PySide on the fly. It also allows switching between Qt4 and Qt5 bindings easily.

python gtk toggle combobox?

Is the equivalent of ToggleButton exist in PyGtk ?
I would like to have a callback like: True or False.
self.liste = gtk.ComboBox(self.liststore)
self.liste.connect("changed", self.result_list)
With this method, the program can't detect if the user clicks again on the same choice.
Thanks
I don't have any specific advice as I haven't used ComboBox much, but I'm pretty sure that what you want to do is possible.
The GTK tutorial says
ComboBox uses a TreeModel (usually a ListStore) to provide the list
items to display.
The basic ComboBox methods are great for simple things, but for more advanced usage you need to play with things at the TreeModel level yourself. To do that effectively, you need to know how they work; fortunately the docs in the tutorial are pretty good: TreeView widget, but also check out the info in the reference manual.
To make the equivalent of a toggle button you can use 14.4.8. Activatable Toggle Cells

Qt - Temporarily disable all events or window functionality?

I have a Qt program with many buttons, user-interactable widgets, etc.
At one stage in the program, I would like all the widgets to temporarily 'stop working'; stop behaving to mouse clicks and instead pass the event on to one function.
(This is so the User can select a widget to perform meta operations. Part explanation here: Get variable name of Qt Widget (for use in Stylesheet)? )
The User would pick a widget (to do stuff with) by clicking it, and of course clicking a button must not cause the button's bound function to run.
What is the correct (most abstracted, sensible) method of doing this?
(which doesn't involve too much new code. ie; not subclassing every widget)
Is there anything in Qt designed for this?
So far, I am able to retrieve a list of all the widgets in the program (by calling
QObject.findChildren(QtGui.QWidget)
so the solution can incorporate this.
My current horrible ideas are;
Some how dealing with all the applications events all the time in one
function and not letting through the events when I need the
application to be dormant.
When I need dormancy, make a new transparent widget which recieves
mouse clicks and stretch it over the entire window. Take coordinates
of click and figure out the widget underneath.
Somehow create a new 'shell' instance of the window.
THANKS!
(Sorry for the terrible write-up; in a slight rush)
python 2.7.2
PyQt4
Windows 7
You can intercept events send to specific widgets with QObject::installEventFilter.
graphite answered this one first so give credit where credit is due.
For an actual example in PySide, here's an example you might draw some useful code from:
my_app.py
from KeyPressEater import KeyPressEater
if __name__ == "__main__":
app = QApplication(sys.argv)
eater = KeyPressEater()
app.installEventFilter(eater)
KeyPressEater.py
class KeyPressEater(QObject):
# subclassing for eventFilter
def eventFilter(self, obj, event):
if self.ignore_input:
# swallow events
pass
else:
# bubble events
return QObject.eventFilter(self,obj,event)

Qt uses CSS to color objects? Is there another way to go about this?

I am learning PyQt from this site. The tutorial is building a widget that colours a square.
In this, they are using CSS to colour the square, rather than give it some sort of concrete property of colour. Why is this? Is there another way to do this without CSS or is this the preferred method? It seems awfully strange..
Every widget has QPalette, that can be modified and accessed via QWidget::palette() and QWidget::setPalette(p).
You can find some useful details here: QPalette in Qt 4.6. CSS is just more clean and simple (and declarative, which is SOoo popular nowadays :) ) way to determine it.
Note, that if you want only to modify your widget's background, there is a convenience method just for you: QWidget::setBackgroundRole(QPalette::ColorRole).
This is one of the strengths of Qt. You can modify the UI with simple CSS. It turns out very nice if you treat correctly. Would you be interested in taking a look at my GhostQt SDK. I am using CSS for my Ghost Menu, to give it rounded corners and apply a transparent background. http://traipse.assembla.com/spaces/ghostqt (It's a side project so there is not much there)

Categories

Resources