I'm using a QStatusBar with couple of QLabels on it. It is positioned on the bottom center. Is it possible to move it a little to the right?
dlgMain = PyQt4.uic.loadUi("widgets/main.ui")
statusBar = QtGui.QMainWindow.statusBar(dlgMain)
label= QtGui.QLabel()
label.setStyleSheet("QFrame { color: Green }")
label.setText("%4.2f$" % statistics.profit)
statusBar.addWidget(label)
QStatusBar is not quite meant to be moved around arbitrarily, although it's certainly doable. In a project of mine, I moved around a QMenuBar, which also is not an everyday task, but it worked out reasonably well *cough cough*.
But since you're still starting, you probably don't want to fight against the intricacies of Qt widget layouting when there's an easier way: Just use a plain QWidget with a QHBoxLayout. You can set this up in the Designer directly, and place it in your window as you desire.
Related
I have a simple QSplitter with a few widgets thrown in:
...
actions_splitter = QSplitter(
Qt.Horizontal,
frameShape=QFrame.StyledPanel,
frameShadow=QFrame.Plain
)
actions_splitter.addWidget(self.systems)
actions_splitter.addWidget(self.events)
actions_splitter.addWidget(self.compass_widget)
actions_splitter.setChildrenCollapsible(False)
...
The resulting splitters function perfectly fine, in that I can hover my mouse over their position, see the cursor change, and drag them around and change the sizes of the neighboring widgets.
The problem is that the handles themselves, the QSplitterHandles, absolutely refuse to have any visual modifications stick to them.
I have tried style sheets:
handle = actions_splitter.handle(0)
handle.setStyleSheet("{background-color: red}")
I have tried adding layouts with widgets to them:
handle = actions_splitter.handle(0)
layout = QHBoxLayout()
widget = QPushButton("HANDLE")
layout.addWidget(widget)
handle.setLayout(layout)
And absolutely nothing is doing anything to change how these handles appear. The only "visual" thing I can change is their width, and that's via QSplitter.setHandleWidth().
Someone please point out the painfully, stupidly obvious thing I'm missing here so I can get on with my life.
Premise
QSplitterHandle is one of the few very specific widgets that don't seem to follow generic QWidget "rules"; the reason is pretty simple: its aim is normally limited to the usage it's intended for, which is being a QSplitter child.
Then, you have to consider that, while pretty "liberal", the stylesheet syntax follows basic but important rules, it depends on the underlying QStyle in use and its behavior might change whenever a child widget is very dependant on its parent, as in this case.
First of all, there's a conceptual problem in your approach: the stylesheet syntax is wrong, as you're trying to use a selector-like syntax (using {braces}) without specifying a selector. With a syntax like that, the stylesheet won't be applied anyway, even with much more "standard" widgets.
But that's not enough. The QSplitter handle() documentation explains an important point (emphasis mine):
Returns the handle to the left of (or above) the item in the splitter's layout at the given index, or nullptr if there is no such item. The handle at index 0 is always hidden.
Even if your syntax were correct, it wouldn't have worked anyway since you tried to apply the stylesheet to the first (hidden) handle.
So, theoretically, the correct syntax should've been the following:
self.splitter.handle(1).setStyleSheet("background-color: red;")
even better:
self.splitter.handle(1).setStyleSheet(
"QSplitterHandle {background-color: red;}")
or, for all handles:
self.splitter.setStyleSheet(
"QSplitterHandle {background-color: red;}")
On the other hand, since QSplitterHandle is a very peculiar widget, its color properties are applied in different ways according to the currently applied QStyle, even when a correct syntax is used. Remember that stylesheets are overrides to the current QStyle, which means that the QStyles states the painting rules, and applies the eventual stylesheet according to those rules.
For instance, while the "windows" style uses the background color rule of the stylesheet to draw the actual background of the handle, the fusion style uses the background color to draw the "dots" of the splitter only.
As with other complex widgets (like QComboBox or QAbstractItemView), you need to use specific selectors for sub-controls, as clearly explained in the QSplitter stylesheet documentation; using the selector you ensure that the color rule is applied to the handle as a whole, no matter the style in use:
self.splitter.setStyleSheet("QSplitter::handle {background-color: red}")
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.
I'm Wondering if somebody knows a better reference than the QT one for style sheets.
I try to change the background of the content from a QToolBox but background-color only changes the header of the toolbox and the background of the content it reveals is left in a standard color.
I then tried to change the bg of QWidget which worked but left me with problems now at Radiobuttons and Checkboxes, i also think changing QWidget isn't a good solution.
The first picture is with Qt standard colors (this is a maya tool)
the second when i change QWidget
http://i.imgur.com/MNlSedx.png?1
http://i.imgur.com/wuplpmw.png?1
I then tried to change the bg of QWidget which worked but left me with
problems now at Radiobuttons and Checkboxes, i also think changing
QWidget isn't a good solution.
No man, It is petty good solution. In your QToolBox stylesheet, your have use QWidget {} it's equivalent to *[class~="QWidget "] so this problem is in subclass has been hanged. To fix it use access specified class like this *[class="QWidget"] {}. Example;
*[class="QWidget"] {
background-color: rgb(0, 0, 255);
}
Useful Qt Stylesheet Reference
In PySide, I am trying to change the overall style of a simple GUI window (a QLabel object), as outlined at the PySide documentation:
http://srinikom.github.io/pyside-docs/PySide/QtGui/QStyle.html#detailed-description
That is, as described at that link, I want to use setStyle to change the overall GUI format to one of the pre-defined GUI styles (e.g., from Windows to Cleanlooks). (As I note below, this goal is different from tweaking colors and such using setStyleSheet, which I already know how to do).
To get started, I first checked what style types I have available:
print QtGui.QStyleFactory.keys()
This revealed many available styles, including 'Cleanlooks'.
Second, based on documentation from three sources (PySide, ZetCode, and Nullege), I tried to change my QLabel style to 'Cleanlooks':
QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('Cleanlooks'))
Unfortunately, this changed nothing. In fact, nothing I enter has changed a single pixel in my Hello World widget. Not sure if relevant, but when I print the output of the previous line of code, I always get None. Full example code is below the fold.
I am in Windows 7, Python 2.7 running within iPython. Based on replies, this seems to be an issue with PyQt4 in Windows 7 too, not just PySide.
Just to be extra clear, I am not asking about how to use setStyleSheets to tweak my widget. This has been addressed decently already:
Styling with classes in Pyside + Python
Example of code I tried (other permutations I tried are shown in comments):
# coding: utf-8
import sys
from PySide import QtGui
class HelloWorldApp(QtGui.QLabel):
def __init__(self):
QtGui.QLabel.__init__(self, "Hello, world!")
self.initUI()
def initUI(self):
QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('Cleanlooks'))
self.show()
def main():
#QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('Cleanlooks')) #crashes program
qt_app=QtGui.QApplication(sys.argv)
#QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('Cleanlooks')) #does nothing
exHell=HelloWorldApp()
sys.exit(qt_app.exec_())
if __name__=="__main__":
main()
The most helpful resource I found, which answered my question, was this wonderful gallery of widgets:
Widget Gallery
It shows the look of pretty much every type of widget under the different styles.
It turns out my "problem" with QLabel was not a bug, but rather that a bare QLabel is so simple that changing its style rarely influences how it looks. That is, when it is the only thing you have in your display, at best it will not be obvious when you change the style (as in my Hello World example in my question).
As expected, when I replaced the simple QLabel in my example with a combobox or other more complex widget, the style differences showed very clearly, just as described in the Widget Gallery.
Note the above Widget Gallery was pointed out when I asked about this at Qt Centre
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))
....