How do I add multiple stylesheet selectors? - python

I'm adding a button to the application 'Nuke'. I've added a QToolButton, and now I want to style it. I removed the border, and now I want to add a :hover.
I seem to be able to only set one stylesheet. How would I go about adding a second selector, given I can only use one stylesheet?
This will override the top one:
snapshotToolButton.setStyleSheet("#SnapShotButton {border : none;}")
snapshotToolButton.setStyleSheet("#SnapShotButton:hover {background-color : yellow;}")
This is my code:
snapshotToolButton = QtWidgets.QToolButton()
snapshotToolButton.setObjectName("SnapShotButton")
snapshotToolButton.setStyleSheet("#SnapShotButton {border : none;}")
snapshotToolButton.setBaseSize(12,12)
snapshotToolButton.setIcon(QtWidgets.QIcon("C:/Users/nfran/.nuke/icons/cameraIcon.png"))
snapshotToolButton.setToolTip("Take Snapshot")
c.parentWidget().layout().insertWidget(0,snapshotToolButton)

The method "setStyleSheet" is SETTING the Stylesheet, not adding a new one, so you keep overriding the one you already set.
To specify multiple styles, try the following:
snapshotToolButton.setStyleSheet("#SnapShotButton {border: none;} #SnapShotButton:hover { background-color: pink; }")

Related

How to control the distance between a Gtk.Frame and Gtk.HBox inside?

Consider this example:
You can see in this window, is a Gtk.Frame, named "Coefficients". Inside of that is a Gtk.HBox. Inside the Gtk.HBox, are ten Gtk.Scales.
What I'd like to do, is control the padding between the Gtk.Frame, and anything that's inside, effectively the Gtk.HBox, or rather, the Gtk.Scales inside of that. How would I go about that?
In case this is important, I'm using Python3 and Gtk3.
I seem to have made progress going about it a quite different way, however there seem to be inconsistencies.
I defined a CSS with the following contents (self is a Gtk.Window):
self._css = b"""
#coeff_container {
padding: 20pt;
}
"""
The Window this is displayed in is composed like this:
Gtk.Window > Gtk.Frame > Gtk.HBox > ten Gtk.Scales
self._hbox = Gtk.HBox()
The Gtk.HBox has the property "name" set like this:
self._hbox.set_name("coeff_container")
self._hbox.set_spacing(20)
Now, as you can see, I've set the spacing to 20, but the padding property is set in the CSS.
Applying the CSS is done as follows:
self._style_provider = Gtk.CssProvider()
self._style_provider.load_from_data(self._css)
Gtk.StyleContext.add_provider_for_screen( Gdk.Screen.get_default(),
self._style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATIONS )
I cannot set the spacing property in CSS, it only works with .set_spacing(int), on the other hand, I can't set padding not in CSS, it is quite confusing like that.

remove padding/margin from QTabBar in QLayout

I have an application where I want the QTabBar to be in a separate VBoxLayout from the QTabWidget area. It sort of works using the code below but I'm having styling problems. Before I separated the QTabBar from the QTabWidget I didn't have any problems but now I can't figure out how to style it the way I want.
#!/usr/bin/env python2
from PyQt4 import QtGui, QtCore
from peaks import *
class mainWindow(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.setWindowFlags(QtCore.Qt.Dialog)
self.tabWidget = QtGui.QTabWidget()
self.tabBar = QtGui.QTabBar()
self.tabBar.setContentsMargins(0,0,0,0)
self.tabWidget.setTabBar(self.tabBar)
self.tabWidget.setTabPosition(QtGui.QTabWidget.West)
self.tabWidget.setIconSize(QtCore.QSize(35, 35))
self.tab1 = QtGui.QWidget()
self.tab2 = QtGui.QWidget()
tabLayoutBox = QtGui.QVBoxLayout()
tabLayoutBox.setContentsMargins(0,0,0,0)
tabLayoutBox.addWidget(self.tabBar)
mainHBox = QtGui.QHBoxLayout()
mainHBox.setContentsMargins(0,0,0,0)
mainHBox.setSpacing(0)
mainHBox.setMargin(0)
mainHBox.addLayout(tabLayoutBox)
mainHBox.addWidget(self.tabWidget)
mainVBox = QtGui.QVBoxLayout()
mainVBox.addWidget(QtGui.QWidget())
mainVBox.addLayout(mainHBox)
self.setLayout(mainVBox)
self.tabWidget.addTab(self.tab1, 'tab1')
self.tabWidget.addTab(self.tab2, 'tab2')
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
app.setStyleSheet(
"QTabBar { alignment: right; }"
"QTabBar::tear { width:0; border: none; }"
"QTabBar::scroller { width:0; border: none; }"
)
main = mainWindow()
main.show()
sys.exit(app.exec_())
However there are a couple of things that I want that I can't figure out how to do:
I want to eliminate the gap between the QTabWidget and the QTabBar. I've been trying various things like setContentsMargins(0,0,0,0) and setting stylesheets but nothing I've tried has worked.
I want QTabBar to be flush with the top of the QTabWidget. Interesting to note that the tabs seem to rapidly switch back and forth between the top whenever the window is resized.
stuff I've looked at:
Qt Use QTabBar in a Different QLayout
http://doc.qt.io/qt-5/stylesheet-examples.html
https://wiki.qt.io/Adjust_Spacing_and_Margins_between_Widgets_in_Layout
update: I can emulate my desired behavior by setting the QTabBar miminumSizeHint() to (15,15) and setting QTabBar::tab { margin-right: -15px; } but this doesn't let me actually click the tabs. there's a space underneath (ie to the right of) the tabs for some reason and I've no idea how to get rid of it.
second update: I've identified the main problem I think. my code uses
self.tabWidget.setTabPosition(QtGui.QTabWidget.West)
to move the tab to the left side but the QTabWidget assumes that there is a tabBar there, hence the extra space. If I do
self.tabWidget.setTabPosition(QtGui.QTabWidget.East)
that blank space shows up at the right. So one thing I can do is set the tabShape directly on the tabBar:
self.tabBar.setShape(QtGui.QTabBar.RoundedWest)
however this leaves a blank space at the top where the QTabWidget expects the QTabBar to be. I can move that space to the right using setTabPosition before setShape but that doesn't solve the problem of actually getting rid of it.
I wasn't able to figure out how to hide the empty space so instead I'm just using a QTabBar + QStackedWidget which is quite easy to implement. In order to make one like a QTabWidget all you need to do is connect QTabBar.currentChanged to QStackedWidget.setCurrentIndex:
self.stacked = QtGui.QStackedWidget()
self.tabBar = QtGui.QTabBar()
self.tabBar.currentChanged.connect(self.stacked.setCurrentIndex)
self.tabBar.setShape(QtGui.QTabBar.RoundedWest)
self.tabBar.updateGeometry()
self.tabBar.setContentsMargins(0,0,0,0)
I also wrote a convenience function that emulates QTabWidget.addTab:
def addTab(self, widget, name):
self.stacked.addWidget(widget)
self.tabBar.addTab(name)
Your problem is that you override the tab bar positioning by adding the tab bar to a layout.
The tab bar is no longer in the tab widget when you use the lines.
tabLayoutBox = QtGui.QVboxLayout()
tabLayoutBox.addWidget(self.tabBar)
These lines re-parent the tab bar. It looks like you just want to use setTabPosition() instead of creating your own tab bar. You don't need to set a new tab bar unless you create a custom tab bar class and want to use that.
I don't know why you would want it in a separate layout, but the other option is use
tabLayoutBox.setSpacing(0)
This is the spacing in between widgets to separate them. That spacing is for widgets. You have a layout in a layout, so setSpacing(0) may not apply to the spacing on a layout. If not you may have to sub-class QVBoxLayout and create your own layout.
EDIT
I've found that insertSpacing works a lot better.
mainHBox.insertSpacing(1, -25)

How to set a style sheet that only affects the parent in PyQT?

I'm trying to customize my UI. I don't know how to make a style sheet entry pertain to anything except the parent and ALL of the children. For example I run this line:
self.lnchTab.setStyleSheet('QWidget { background-color: #1d1d1d ; color: #f8f8f8}')
And I change ALL of the elements beneath self.lnchTab to be darkish grey. I want only the self.lnchTab to be dark grey, and not the text, inputs, and buttons within it.
How do I accomplish this?
Thanks for any help. Google is giving nothing useful or even near what I'm trying to find.
You can give self.lnchTab object some name/id and then you can use id-selector in style-sheet:
self.lnchTab.setObjectName("myParentWidget");
self.lnchTab.setStyleSheet('QWidget#myParentWidget { background-color: #1d1d1d ; color: #f8f8f8}')

How to get the margin between menu items in pyjamas or gwt?

I have implemented a MenuBar using pyjamas as:
from pyjamas.ui.RootPanel import RootPanel
from pyjamas.ui.Composite import Composite
from pyjamas.ui.MenuBar import MenuBar
class Menubar(Composite):
def __init__(self):
Composite.__init__(self)
menubar = MenuBar(vertical=False)
menubar.addItem("Dashboard", "")
menubar.addItem("FileInspect", "")
self.initWidget(menubar)
RootPanel().add(Menubar())
But by all means i have tried, i am unable to get the margin/space between the menuitems "Dashboard" and "FileInspect". Your suggestions are warmly appreciated.
In GWT you can add a MenuItemSeparator between any pair of menu items that you want to separate. The width of the separator determines the separation between items. You can set the style for your separator such that it appears invisible. For example,
private MenuBar myMenuBar=new MenuBar(false); // false for horizontal menu bar
private MenuItemSeparator separator=new MenuItemSeparator();
private MenuItem item1;
private MenuItem item2;
myMenuBar.add(item1);
myMenuBar.add(separator);
myMenuBar.add(item2);
separator.setStyleName("separatorStyle");
In your CSS you define separatorStyle. For example, if you want a 20px separation...
.separatorStyle{
width: 20px;
padding: 0px;
margin: 0px;
border: none;
background: none;
}
OK so first look in the api documentation at http://pyjs.org/api/ and look for menubar (Ctrl+F finds it ok) or if you're lazy then you can see it here: http://pyjs.org/api/pyjamas.ui.MenuBar.MenuBar-class.html
That doesn't help in this case because there's no setSpacing() method or similar but at least it tells us that for sure.
So I guess you have to do it via css. Look in the showcase example:
pyjamas/examples/showcase/src/public/Showcase.css
Now you'll see there's a gwt-MenuBar class right at the top. So you've got two choices; either use the addStyleName() method of the MenuBar widget or just edit the existing style in the css. I'd probably do the latter.
Hope that helps!! Don't forget to accept if it does.

pyqt - how to remove the boder from a widget in the statusbar?

I am using QLabel widgets to display error messages to the user in the status bar. This is working fine with the following code;
self.statusbar = self.statusBar()
label = QtGui.QLabel("this is a test error message")
stylesheet = """
QLabel {
font-weight: bold;
color: #FF0000;
}
"""
label.setStyleSheet(stylesheet)
self.statusbar.addWidget(label)
The only problem is that the widgets have a border around them that I can not get rid of. This is not functionally a problem as the message is still visible but it does look rather ugly and I'd like to get rid of it. I can not work out where it is coming from. Whether it is something I need to set on the statusbar or the widget. I have tried modifying the stylesheet for both the statusbar and label to add "border: 0px" to no avail. I have tried setting the labels frame to label.setFrameShape(QtGui.QFrame.NoFrame) but that doesnt seem to be it either.
Anyone have any ideas how I can get rid of it?
You do this with Style sheets. You probably have a line like this
Application app(argc, argv);
underneath that, add one like this:
app.setStyleSheet("QStatusBar::item { border: 0px solid black }; ");
and those pesky boxes will be gone.
try using self.statusbar.showMessage('this is a test error message'), as the QStatusBar is not designed for showing labels. If you need more frexibility than this you may consider subclassing QStatusBar and changing its paintEvent function to special-case labels. Either of these approaches will be much easier to maintain than setting stylesheets for each label you want to but on there anyway, but as usual, YMMV.
for more info check out the manual page for QStatusBar

Categories

Resources