I'm pretty new to this Qt thing and its whole stylesheet system. My background of HTML/CSS helps a little to understand the system, but a lot of things just happens for no apparent reason....or don't happen.
Anyway, the mystery of the HLINE and the VLINE and how to change the lines' color is just a mystery for me. I learned from other questions and various fora that it's linked to the QFrame elements. And I can change the color of the line if I just use something like
QFrame
{
color: red;
}
But this of course changes the color of tons of other things that uses a QFrame as well. I could of course go into the HLINE element and put color: red; in there and that works fine, but my app requires that I put everything in a single stylesheet that gets loaded into the app. So styling individual elements is not an option.
A solution would look something like
QFrame HLine, QFrame VLine
{
color: red;
}
QFrame[frameShape="4"] /* QFrame::HLine == 0x0004 */
{
color: red;
}
QFrame[frameShape="5"] /* QFrame::VLine == 0x0005 */
{
color: green;
}
HLine and VLine are tricky to style. It's worth taking a look at the "Detailed Description" section of the documentation. For a quick fix, I found that this set of rules allows customizing the appearance of such lines via stylesheet in a reliable and relatively clean manner:
QFrame[frameShape="4"],
QFrame[frameShape="5"]
{
border: none;
background: red;
}
This works regardless of the frameShadow property, which otherwise affects their appearance and the effect of style rules. Keep in mind that the width of the lines are not 1px by default -- this can be changed using the min-width, max-width, min-height or max-height properties, as appropriate.
For a more detailed overview of my findings, read along.
Most QFrames have the QFrame::Plain frameShape by default, but HLine and VLine's default frameShape is QFrame::Sunken. This means that they are not really lines, but thin boxes that contain a mid-line that's used to provide the 3D effect. From the documentation:
The mid-line width specifies the width of an extra line in the middle of the frame, which uses a third color to obtain a special 3D effect. Notice that a mid-line is only drawn for Box, HLine and VLine frames that are raised or sunken.
If you set the frameShape to Plain, this midline is still visible, and can be styled with the color property (note: that's not a background-color or border-color!)
But this doesn't work for a HLine/VLine that's left with the default Sunken appearance. One way to fix this could be to set separate styles for Plain and Sunken QFrames by using attribute selectors with the decimal values of the property enums (which are described in the documentation in hehadecimal), like so:
/* Reference (from doc.qt.io/qt-5/qframe.html#types):
* - frameShape[4] --> QFrame::HLine = 0x0004
* - frameShape[5] --> QFrame::VLine = 0x0005
* - frameShadow[16] --> QFrame::Plain = 0x0010 (default for most widgets)
* - frameShadow[48] --> QFrame::Sunken = 0x0030 (default for HLine/VLine)
*/
QFrame[frameShape="4"][frameShadow="16"],
QFrame[frameShape="5"][frameShadow="16"]
{
...
}
QFrame[frameShape="4"][frameShadow="48"],
QFrame[frameShape="5"][frameShadow="48"]
{
...
}
but since the styles that work for HLine/VLine with QFrame::Sunken also work for those with QFrame::Plain, it's usually a waste to do so. I show them above for educational value only about how to use attribute selectors.
The best approach is to treat the QFrame as the box that it is, and either (1) set border-top or border-right coupled with a max-height: 0px (or max-width for a VLine), to ensure the inside of the box doesn't take up space in the layout; or (2) use a background color coupled with border: none (in which case, max-height/width should be 1 or larger, otherwise the QFrame is invisible). The latter is the solution I'd recommend, as shown in the first code block above.
Hope this helps!
According to QDarkStyleSheet issue, You could use:
QFrame[width="3"], QFrame[height="3]
These selectors, they seem to work cross-platform, and they are unlikely to change.
Probably better than using enum values as ints, as they are likely to change with Qt versions, and line styling are not, as they fulfill certain requirements.
but my app requires that i put everything in a single stylesheet that
gets loaded into the app.
You can use Conflict Resolution. Suppose that you have a QMainWindow object with lots of widgets on it . Set these style sheets for the maindionw style sheet :
QLabel#label{
background-color: rgb(255, 170, 255);
}
QPushButton#pushButton{
color: rgb(0, 0, 255);
}
QFrame#line{
background-color: rgb(0, 170, 255);
}
The first css just changes a QLabel name label on your mainwindow and set its back color to rgb(255, 170, 255). The next will change text color of a QPushButton named pushButton to (0,0,255);. The third one change property of a line.Lines are just a QFrame.
So the solution that I can offer is to place your css in a file and then load this file using QFile and QTextStream and then set the contents of the file for css of your main winodw or main widget using setStyleSheet ( const QString & styleSheet ) function. or If you are using creator just right click on your main window and select change stylesheet and then paste your css. But bear in mind that you should use conflict resolution.
You can leave Qt's hlines and build up your own very easy. For frames you want looks like hline add property "class" as "HLine" (for example), in designer or in c++ code:
frame->setProperty("class", "HLine")
.
Then, you can define in main view's or in global app stylesheet something like this:
QFrame.HLine {
border: none;
border-bottom: 2px solid red;
}
and you will get horizontal two pixels red line.
Related
I love to have a very compact theme for eclipse. It use to be simple with GTK2, but now with oxygen, I've more and more things that are broken and I'm trying to get an ok compact style with GTK3.
I read a lot of things on it and the main win was to just use "minwaita" theme. It helps a lot!
But I still have an horrible 16px width lost due to perspective swticher.
I found it thanks to the "e4 spies" plugin and I even succesfully set some properties as can be seen on the following image:
So, the problem is the green part. And I see that it is due to some SWT property, as reported by e4 css spy on the element:
CSS Properties:
eclipse-perspective-keyline-color: rgb(88, 88, 88);
handle-image: none;
color: rgb(255, 255, 255);
background-color: rgb(0, 255, 0);
CSS Classes:
MToolControl
Draggable
HIDEABLE
SHOW_RESTORE_MENU
CSS ID:
PerspectiveSwitcher
SWT Style Bits:
SWT.LEFT_TO_RIGHT
SWT.DOUBLE_BUFFERED
CSS Class Element:
org.eclipse.e4.ui.css.swt.dom.CompositeElement
SWT Layout: RowLayout {type=SWT.HORIZONTAL marginLeft=8 marginTop=6
marginRight=8 marginBottom=4 spacing=3 wrap=true pack=true
fill=false justify=false}
Bounds: x=1877 y=190 h=154 w=43
I tried to override that last part with margin-left and/or padding-left, with value of 0 and -8px, on it, on parent, on children. Nothing seems to work.
So, does anybody know if it's possible, and if so how to override the SWT Layout marginLeft and margingRight properties ?
Looking at the Eclipse CSS element definitions 'padding' values are only available on CTabFolder.
'margin-xxx' values can be set for any control but the Composite containing the control must be using GridLayout and a flag called CSSSWTConstants.MARGIN_WRAPPER_KEY must be set in the composite's data.
Since the composite you are looking at seems to be using RowLayout the margins can't be set (unless you write your own property handler).
Note: CSS element properties are defined using the org.eclipse.e4.ui.css.core.elementProvider extension point and are mostly in the org.eclipse.e4.ui.css.swt plugin. The 'margin-xxx' properties are dealt with by the org.eclipse.e4.ui.css.swt.properties.css2.CSSPropertyMarginSWTHandler class.
I'd like color: red to automatically be rendered as color: #DB0000 by the browser. Instead of setting the style for "red" in our application as color: red, I want to use a different color than the system-defined definition of red. Our application uses a different "red" color than the standard setting for setting the color: red style in css. Other than creating a class and using that class where I need to set the style (I'm afraid developers could forget to use this class and instead set color: red), is there a way to automatically override the defined color for color: red and override it with my own setting of color: #DB0000?
No, there isn't a possibility like this in plain CSS.
However, in SASS and LESS (both CSS preprocessors) you can define varibles. So you can for example define #red1: #DB0000 as a variable and later on use color: #red1 or border-color: #red1 in as many CSS rules as you like.
That's not possible with CSS, but if you use SASS, you can create a macro to change the color, although that still might not work.
EDIT: After doing some spelunking on my own, there is a way to use variables in pure CSS (no SASS!):
:root {
--red: #DB0000; /* Define your custom value */
}
p {
color: var(--red); /* Reference your custom value.
All <p> elements will be given
a text color of #DB0000 */
}
Check out this CodePen
Source: https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables
New to Polymer, and the docs seem a little 'light' on examples. I'm trying to style a dropdown menu so everything is white on a blueish background. Most things (tabs, toast, etc.) are working, but the dropdown-menu stubbornly refuses to show the little 'arrow' button in anything other than murky grey.
Example JSBin
The styling code is:
<style>
:host {
display: block;
/* Main vars */
--ki-teal: #4790A8;
--paper-tabs-selection-bar-color: #fff;
--paper-tab-ink: #fff;
/* Toolbar colours */
paper-toolbar.ki {
--paper-toolbar-background: var(--ki-teal);
}
/* Project select dropmenu colours */
paper-dropdown-menu-light.ki {
--paper-dropdown-menu-color: #fff;
--paper-dropdown-menu-focus-color: #fff;
--paper-dropdown-menu-button: {
color: #fff;
}
--paper-input-container-color: var(--ki-teal);
--paper-input-container-focus-color: #fff;
--paper-dropdown-menu-input: {
border-bottom: none;
};
}
/* Notifications */
#toastSave {
--paper-toast-background-color: var(--ki-teal);
--paper-toast-color: white;
}
}
</style>
But the --paper-dropdown-menu-button doesn't seem to have any effect, or I'm not using it right. Any guidance appreciated.
In addition, you'll see (at least on Chrome/Windows) that the underline bar when the dropdown has focus is not aligned properly with the active tab bar. I guess that's just a Polymer CSS glitch which will get worked out eventually, unless it's something I need to take care of in the <style> section as well?
Use --iron-icon-fill-color in your paper-dropdown-menu class if you want have other iron-icons also which you don't want to style, else you can style use it in host if you want.
Another way of doing it will be giving color to mixin --paper-dropdown-menu-icon. As per paper-dropdown-menu documentation it is
A mixin that is applied to the internal icon
Lastly, if you look at the code of paper-dropdown-menu-light you'll notice that icons have default value as --disabled-text-color. So, if you change this value that should do the trick for you. I'll recommend not to use this method as this is a default variable for material design theme and Polymer has used this as default value at lot of places. So, unless to know what you are doing avoid this method.
In Polymer if an element is using some other element internally you can always refer the style guide of internal element and use it directly. Like here we are using iron-icons styles to style the icon which is inside paper-dropdown-menu
I don't think Polymer has directly mentioned this in their styling guide but you can find this detail written at the end of styling details of paper-dropdown-menu and generalise it
You can also use any of the paper-input-container and paper-menu-button style mixins and custom properties to style the internal input and menu button respectively.
When I use
myButton->setCheckable(true);
There is -I don't know how to call it- a sort of grid :
Is it possible to not have this grid and here just my green background ?
Use the checked property:
QPushButton:checked{
background-color: ...
border: none;
}
Same applies for pressed if you want to alter that too.
Note: You can read all about the properties here (just search for QPushButton to find the properties that are part of the button. Removing the border seems to be necessary based on the documentation (otherwise the background colour might not be applied).
I have a QLabel with a Qt stylesheet that sets a dark background:
QLabel {
background: black;
color: white;
}
This works fine until I add text with an embedded URL and set the Qt::TextFormat to Qt::RichText. The link displays as the default dark blue, which is hard to read on a dark background.
I've tried customising it via a stylesheet such as:
a { color: white; }
QLabel!visited { color: white; }
but this doesn't have any effect. The one thing that does seem to work is changing the application's QPalette:
QPalette newPal(qApp->palette());
newPal.setColor(QPalette::Link, Qt::white);
newPal.setColor(QPalette::LinkVisited, Qt::white);
qApp->setPalette(newPal);
However this requires the colour to be hardcoded. Is there any way I can set the colour from a stylesheet instead?
EDIT:
I've discovered a further problem with customising the palette. If I want to just modify the palette of my widget (substituting widget for qApp in the sample above) then this doesn't work. I don't want to affect all the other QLabels in the app, so how do I limit the palette changes to this widget?
One way is to add style="color: whatever" or a class to the inner <span> of the link. I haven't figured out yet how to apply this to the whole application but it's a good start.
I've had little success explicitly setting the QPalette -- it works if you set it for the entire application, but not if you set it in the widget. In the end though, the easiest thing for what I needed to do was use a QTextBrowser instead which supports a subset of HTML. I could then override the colour of links using a regular CSS stylesheet:
QTextBrowser browser;
// IMPORTANT! - set the stylesheet before the content
browser->document()->setDefaultStyleSheet("a {color: white; }");
browser->setText(html);
Short answer is no. Recently I had to do this.
QLabel!visited doesn't work because Qt doesn't track whether QLabel were visited or not.
QLabel { color: ... } doesn't work for links. Can't find why but all I found is a suggestion to use QPallete in this case.
You can set the color tag in the HTML to
{ color: inherit; }