Is it possible to use custom scalable images for a QRadioButton? - qt

With a simple QPushButton, if I want to use custom images while the size of the button is determined by a layout (so it can be scaled freely), the only possibility is to override border-image in the style sheet. If I add the image as an image attribute instead of border-image, then the images are not scaled down.
However, if I use a QRadioButton and override the image or border-image, the circle of the radio button remains visible. I found no way of hiding it or overriding it.
A possibility would be to ignore the label, and change the circle icon itself. This can be done by overriding QRadioButton:indicator, however, it doesn't accept border-image, it only accepts image which will not scale.
Is there any way to solve this, or am I stuck with using QPushButton with setCheckable(true), and handle the other buttons manually whenever one of them is pressed?
I tried specifying a border-image for the label, and a non-existing image for the indicator:
ui->radioButton->setStyleSheet(
"QRadioButton { border-image: url(:/img/off.png) 0 0 0 0 stretch stretch; }"
"QRadioButton:checked { border-image: url(:/img/on.png) 0 0 0 0 stretch stretch; }"
"QRadioButton:pressed { border-image: url(:/img/off_pressed.png) 0 0 0 0 stretch stretch; }"
"QRadioButton:checked:pressed { border-image: url(:/img/on_pressed.png) 0 0 0 0 stretch stretch; }"
"QRadioButton:indicator:unchecked {image: url()}"
"QRadioButton:indicator:checked {image: url()}"
"QRadioButton:indicator:unchecked:pressed {image: url()}"
"QRadioButton:indicator:checked:pressed {image: url()}"
);
The problem is, that although the circle is now not visible, it still takes up space, so the image doesn't fill up the entire available space.

Reducing the size of the indicator to zero seems to work. It's still an ugly hack (as Qt still doesn't support scalable images for buttons and labels unless they are defined as border image), but it works.
ui->radioButton->setStyleSheet(
"QRadioButton { border-image: url(:/img/off.png) 0 0 0 0 stretch stretch; }"
"QRadioButton:checked { border-image: url(:/img/on.png) 0 0 0 0 stretch stretch; }"
"QRadioButton:pressed { border-image: url(:/img/off_pressed.png) 0 0 0 0 stretch stretch; }"
"QRadioButton:checked:pressed { border-image: url(:/img/on_pressed.png) 0 0 0 0 stretch stretch; }"
"QRadioButton:indicator {width: 0px; height: 0px;}"
);
A disadvantage of this solution is that a bunch of QPianter errors are printed to stdout, seemingly because of the non-existent indicator:
QPainter::begin: Paint device returned engine == 0, type: 3
To avoid this, I created an 1x1 pixel completely transparent png image
"QRadioButton:indicator {width: 1px; height: 1px; image: url(:/img/empty.png)}"
This works just as well, without generating QPainter error messages.
Edit:
As Maxim Paperno commented, this also works:
"QRadioButton:indicator {image: null}"

Related

How to expand Table Row border

currently I have borders around all my rows. I'm looking to style the borders so they grow past the table on the left and right by a couple pixels. At the moment they all remain within the table
I hard coded the border with the following styles
--outline-box-shadow-color: ${colorTheme.primary.base};
&:focus {
box-shadow: 0 0 0 2pt var(--outline-offset-box-shadow-color), 0 0 0.75pt 3.5pt var(--outline-box-shadow-color);
}
https://jsfiddle.net/o0tev173/
Looking to have it extend a bit out like this on both left and right.
Any tips or suggestions is greatly appreciated.
Add a box shadow with a negative x value and no blur like so:
#TR_8, #TR_18, #TR_28, #TR_38 {
box-shadow: -6px 0 0 #369;
}
You can combine that with your current box-shadow value or use that by itself.

CSS3 box-shadow rendering issue in Firefox

Box-shadow renders incorrectly in firefox (was observed on v49).
Css:
.block {
width: 90px;
height: 90px;
box-shadow: 0 0 0 1px #0084A3;
border-radius: 100%;
}
It renders asymmetrically and depend on window height.
Here's the fiddle. Try to resize the window vertically and see what is happening to box-shadow. It's easy to achieve something like this:
invalid box-shadow rendering. You can see that top shadow is much wider than bottom one.
Chrome and Safari handles it well.
I would appreciate any helpful ideas.
Please use box-shadow: inset 0 0 0 1px #0084A3; it gives same output in both firefox and chrome browsers.
Try this -moz-box-shadow: 0 0 0 1px #0084A3; for Firefox;
San is right but Just for more detail..
There is 2 type of shadow
1. Inner ( inset )
2. Outer ( default )
so in css3, by default it is taking outer shadow if you are not specified inset property.
inset
If not specified (default), the shadow is assumed to be a drop shadow (as if the box were raised above the content).
The presence of the inset keyword changes the shadow to one inside the frame (as if the content was depressed inside the box). Inset shadows are drawn inside the border (even transparent ones), above the background, but below content.
check this link for more detail

border-image-repeat: space not working

I've met a small problem that I cannot seem to solve.
This is my CSS code that should work:
div.menu-menu_hun-container li {
padding: 5px;
font-size: 18px;
-moz-border-image:url("images/menu-border.png") 0 0 1 0;
-webkit-border-image:url("images/menu-border.png") 0 0 1 0;
border-image:url("images/menu-border.png") 0 0 1 0;
border-width: 1px;
border-image-repeat: space;
}
As you can see, I'm trying to add a border image only to the bottom of each menu element (except the last one as it's already solved). The problem is that the space property doesn't work at all. Menu elements are 187px width and the image is 125px. I want to position the border element to the left to cover 2/3 of the bottom line. Perhaps, I do not understand how this property works, but I think it should position a single image element to the center of the bottom border because there's no more space left for another image element to make the border complete. I hope you guys could clear the mess in my head.
If you can provide fiddle or image, it will be nice, anyway, Try to re-size the image and use border-image-repeat: space; or you can use round property.

Border Image Confusion [duplicate]

I've used border, border-top-image, border-image and none seem to do what I am after.
I have the following CSS:
#footer {
overflow: hidden;
clear: both;
width: 100%;
margin: 0 auto;
padding: 26px 0 30px 0;
border-top-image: url('http://www.mycelticcrossstitch.com/celtic%20knot%20cross%20stitch.jpg');
font-size: 0.8461538461538462em;
color: #aaa;
}
This does not seem to apply to the website I am trying to work on, I've tried it in Firefox and Chrome.
I only want the image to appear on the top border and wish to have no other borders (so it's sort of like a <hr />)
I don't think that there is any such property like border-top-image to give image border to any side of an element -
Use
border-image:url('http://www.mycelticcrossstitch.com/celtic%20knot%20cross%20stitch.jpg') 30 30 round;
but it give border around all sides. To remove border around rest of the sides I gave -
border-bottom:0;
border-left:0;
border-right:0;
It worked and here is my fiddle - http://jsfiddle.net/ashwyn/c7WxG/1/
There is the border-image-width: a b c d; property. The details:
a-d are the widths of the top, right, bottom and left borders, respectively
values of a-d may be in the form:
[x]px
[x] - multiples of border-width value
[x]% - percent of the image slice (appears non-working in Safari 7)
auto - derive from the width of the corresponding image slice
the default value is 1.
if you omit d, the value of b is used for the left border width
if you also omit c, the value of a is also used for the bottom border width
if you also omit b, the value of a is used for all borders :)
So for your example you could use:
border-image-width: 100% 0 0 0;
Alternatively the border-image shorthand property includes border-image-width as a parameter, so in one line of CSS:
border-image: url(image.png) 100% 0 0 0 / [desired_border_width]px 0 0 0 repeat;
This uses the entire image for the top slice ("100% 0 0 0") and applies it as the top border at the desired width.
Another SOLUTION - create visual "BEFORE" phseudo-element :
.yourDiv::before{
background:url("http://lorempixel.com/200/100/");
width:100%;
height:20px;
}
You said you wish to have no other borders, so instead of border-image-width you can also simply use the border-width shorthand :
see https://jsfiddle.net/j2x6n3q9/
The border image is specified as a URI, for two different groups:
The URI of upto three images may be specified for each of the four border edges. If one image URI is given, the first tile is centered on the border line. If two image URIs are given, they meet at the center of the border line with the first image placed on the top or left side of the center. If three image URIs are given, the second becomes the center and does not tile. The other two are placed on either side of the center image, with the first going on the top or left side of the center and the third going on the bottom or right.
For more refer w3.org

Top Border Image in CSS3

I've used border, border-top-image, border-image and none seem to do what I am after.
I have the following CSS:
#footer {
overflow: hidden;
clear: both;
width: 100%;
margin: 0 auto;
padding: 26px 0 30px 0;
border-top-image: url('http://www.mycelticcrossstitch.com/celtic%20knot%20cross%20stitch.jpg');
font-size: 0.8461538461538462em;
color: #aaa;
}
This does not seem to apply to the website I am trying to work on, I've tried it in Firefox and Chrome.
I only want the image to appear on the top border and wish to have no other borders (so it's sort of like a <hr />)
I don't think that there is any such property like border-top-image to give image border to any side of an element -
Use
border-image:url('http://www.mycelticcrossstitch.com/celtic%20knot%20cross%20stitch.jpg') 30 30 round;
but it give border around all sides. To remove border around rest of the sides I gave -
border-bottom:0;
border-left:0;
border-right:0;
It worked and here is my fiddle - http://jsfiddle.net/ashwyn/c7WxG/1/
There is the border-image-width: a b c d; property. The details:
a-d are the widths of the top, right, bottom and left borders, respectively
values of a-d may be in the form:
[x]px
[x] - multiples of border-width value
[x]% - percent of the image slice (appears non-working in Safari 7)
auto - derive from the width of the corresponding image slice
the default value is 1.
if you omit d, the value of b is used for the left border width
if you also omit c, the value of a is also used for the bottom border width
if you also omit b, the value of a is used for all borders :)
So for your example you could use:
border-image-width: 100% 0 0 0;
Alternatively the border-image shorthand property includes border-image-width as a parameter, so in one line of CSS:
border-image: url(image.png) 100% 0 0 0 / [desired_border_width]px 0 0 0 repeat;
This uses the entire image for the top slice ("100% 0 0 0") and applies it as the top border at the desired width.
Another SOLUTION - create visual "BEFORE" phseudo-element :
.yourDiv::before{
background:url("http://lorempixel.com/200/100/");
width:100%;
height:20px;
}
You said you wish to have no other borders, so instead of border-image-width you can also simply use the border-width shorthand :
see https://jsfiddle.net/j2x6n3q9/
The border image is specified as a URI, for two different groups:
The URI of upto three images may be specified for each of the four border edges. If one image URI is given, the first tile is centered on the border line. If two image URIs are given, they meet at the center of the border line with the first image placed on the top or left side of the center. If three image URIs are given, the second becomes the center and does not tile. The other two are placed on either side of the center image, with the first going on the top or left side of the center and the third going on the bottom or right.
For more refer w3.org

Resources