Change QWidget Title Color - c++

I have a custom class called Window that extends QWidget.
#include "window.h"
// This is the base that all (MDI) sub-windows extend off
Window::Window()
{
// Add fake icon to remove icon in all
setWindowIcon(QIcon("."));
}
void Window::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
css:
QWidget:title
{
background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #ca0619);
}
When I do this the buttons (minimize, maximize and close) disappear (as seen in the picture below).
So my question, how do I properly style my Window titlebar?

Related

Circle user avatar issue

I want to make QLabel with the image circle:
Code:
QLabel *label = new QLabel(this);
QPixmap avatarPixmap(":/Icon/default_avatar.png");
label->setPixmap(avatarPixmap);
label->setStyleSheet("border: 0.5px solid red; border-radius: 50%; background-clip: padding;");
It only rounds the QLabel, not the image. How to fix it? Thanks.
Update:
The only way is to override the paintEvent for QLabel
Code:
void AccountImage::paintEvent(QPaintEvent *event)
{
QPixmap pixmap(":/Icon/default_avatar.png");
QBrush brush(pixmap);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(brush);
painter.drawRoundedRect(0, 0, width(), height(), 100, 100);
QLabel::paintEvent(event);
}
The image is rounded but not properly scaled. Any ideas?
try to set mask on the label like:
int w = // set the width here
int h = // set the height here
QRect *rct = new QRect(0, 0, w, h);
QRegion *reg = new QRegion(*rct, QRegion::Ellipse);
label->setMask(*reg);
see: http://doc.qt.io/archives/qt-4.8/qwidget.html#setMask
The solution by overriding QLabel paintEvent method.
Code:
void AccountImage::paintEvent(QPaintEvent *event)
{
QPixmap pixmap(":/Icon/my_avatar.png");
QPixmap scaled = pixmap.scaled(width(), height(), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
QBrush brush(scaled);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(brush);
painter.drawRoundedRect(0, 0, width(), height(), 100, 100);
QLabel::paintEvent(event);
}
Result:

CompositionMode_Clear gives me a black rectangle

I've trying to draw a circle with the center transparent using Qt in paintEvent.
I have this code:
void CircleWidget::paintEvent(QPaintEvent * event)
{
QPainter painter;
QPixmap pix1(width(), height());
QPixmap pix2(width()/2, height()/2);
QBitmap mask1(pix1.size());
QBitmap mask2(pix2.size());
mask1.fill(Qt::color0);
mask2.fill(Qt::color0);
pix1.setMask(mask1);
pix2.setMask(mask2);
if (painter.begin(&pix1))
{
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(QBrush(QColor(0xff, 0x0, 0x0)));
painter.drawEllipse(0, 0, width(), height());
painter.end();
if (painter.begin(&pix2))
{
painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(QBrush(QColor(0x0, 0xff, 0xff)));
painter.drawEllipse(0, 0, width()/2, height()/2);
painter.end();
if (painter.begin(this))
{
painter.drawPixmap(0, 0, pix1);
painter.setCompositionMode(QPainter::CompositionMode_Clear);
painter.drawPixmap(width()/4, height()/4, pix2);
painter.end();
}
}
}
}
But, the result is this:
Do you have any idea? Thanks a lot.

Making only a part of QTableWidgetItem have background [duplicate]

How can I set the background color for a part of the background like in the following image:
Of course, without border frames, I want to set only the cyan color.
I need to set the length of the left part (cyan) as the percentage of the widget length, e.g 30%.
With css I would hack qlineargradient a little bit. Note that edge of cyan may be a little blurry.
QFrame
{
background-color: qlineargradient(x1:0, x2: 1, stop: 0 cyan, stop: 0.29 cyan, stop: 0.2901 white, stop: 1 white);
}
If you want it hard-coded in the application, you can overload the paintEvent function in a widget. Something like this:
void MyWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
QPen pen(Qt::NoPen);
painter.setPen(pen);
painter.fillRect(0, 0, width(), height(), Qt::white);
painter.fillRect(0, 0, 0.3*width(), height(), Qt::cyan);
...
}

SDL: Fullscreen translucent background

I'm trying to write a program that has a translucent background covering the whole screen. After some research it appeared that SDL would be the way to go.
I've written the code to create a full screen window with a background whose alpha is equal to 100 (out of 255), but for some reason it just draws the solid colour. What have I done wrong?
// Initialise SDL
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
this->throwSDLError("SDL_Init Error");
}
// Create the window and renderer
if (SDL_CreateWindowAndRenderer(0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP, &(this->window), &(this->renderer)) != 0) {
this->throwSDLError("Could not create the window and renderer");
}
// Set the blend mode to specify how the alpha channel is used
if (SDL_SetRenderDrawBlendMode(this->renderer, SDL_BLENDMODE_BLEND) != 0) {
this->throwSDLError("Could not set render draw blend mode");
}
// Set the colour to draw
if (SDL_SetRenderDrawColor(this->renderer, 200, 200, 200, 100) != 0) {
this->throwSDLError("Could not set the drawing colour");
}
// Clear the screen using the colour
if (SDL_RenderClear(this->renderer) != 0) {
this->throwSDLError("Could not render the screen");
}
// Present the rendered screen
SDL_RenderPresent(this->renderer);
On Windows, you can create a transparent window by using SetLayeredWindowAttributes to chroma-key the background color from a borderless SDL window.
Code:
// SDL window with transparent background v1.2
#include <SDL.h>
#include <SDL_syswm.h>
#include <Windows.h>
// Makes a window transparent by setting a transparency color.
bool MakeWindowTransparent(SDL_Window* window, COLORREF colorKey) {
// Get window handle (https://stackoverflow.com/a/24118145/3357935)
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version); // Initialize wmInfo
SDL_GetWindowWMInfo(window, &wmInfo);
HWND hWnd = wmInfo.info.win.window;
// Change window type to layered (https://stackoverflow.com/a/3970218/3357935)
SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
// Set transparency color
return SetLayeredWindowAttributes(hWnd, colorKey, 0, LWA_COLORKEY);
}
int main(int argc, char** argv) {
// Get resolution of primary monitor
int desktopWidth = GetSystemMetrics(SM_CXSCREEN);
int desktopHeight = GetSystemMetrics(SM_CYSCREEN);
SDL_Window* window = SDL_CreateWindow("SDL Transparent Window",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
desktopWidth, desktopHeight, SDL_WINDOW_BORDERLESS);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
// Set background color to magenta and clear screen
SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255);
SDL_RenderClear(renderer);
// Draw blue square in top-left corner
SDL_Rect rect1 = {0, 0, 100, 100};
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
SDL_RenderFillRect(renderer, &rect1);
// Draw red square in center of the screen
SDL_Rect rect2 = {(desktopWidth-100)/2, (desktopHeight-100)/2, 100, 100};
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
SDL_RenderFillRect(renderer, &rect2);
// Add window transparency (Magenta will be see-through)
MakeWindowTransparent(window, RGB(255, 0, 255));
// Render the square to the screen
SDL_RenderPresent(renderer);
// Loop until user quits
bool quit = false;
SDL_Event event;
while (!quit) {
while (SDL_PollEvent(&event) != 0) {
if (event.type == SDL_QUIT) {
quit = true;
}
}
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Result:
Explanation:
First, create a borderless window with that covers the entire desktop. Choose a solid masking color and use it as your background. (In my case, I used magenta). You can then key-out your masking color with the Win32 API function SetLayeredWindowAttributes.
Any part of the window with this color will be completely see-through. Other windows behind your program can be interacted with as normal. By default, other applications can be moved on top of your borderless window.
If you want your SDL window to always be on top of other windows, you can set the SDL_WINDOW_ALWAYS_ON_TOP flag when creating your window.
See Also
Stack Overflow: Creating a transparent window in C++ Win32
Stack Overflow: How detect current screen resolution?
Microsoft: Layered Windows

Why QPainter might reject to work inside paintEvent?

I have:
class QTextEditEnter : public QTextEdit
{
Q_OBJECT
public:
QTextEditEnter( QWidget *_parent ) : QTextEdit(_parent)
{
this -> setFrameStyle( QFrame::Sunken ); // Sunken!
}
protected:
virtual void keyPressEvent(QKeyEvent * event);
virtual void paintEvent(QPaintEvent *_event)
{
QTextEdit::paintEvent( _event );
QPainter pnt(this);
pnt.setPen( QColor( 0, 0, 0, 0xff ));
pnt.drawRect( 0, 0, width(), height());
}
signals:
void signalPressEnter();
};
that gives:
QPainter::begin: Widget painting can only begin as a result of a paintEvent
QPainter::setPen: Painter not active
QPainter::drawRects: Painter not active
QPainter::begin: Widget painting can only begin as a result of a paintEvent
QPainter::setPen: Painter not active
QPainter::drawRects: Painter not active
Why that could be?
Update
// QPainter( this )
// QTextEdit::paintEvent at the begining of custom PaintEvent
// RESULT: "QPainter::begin: Widget painting can only begin as a result of a paintEvent" ...
virtual void paintEvent(QPaintEvent *_event)
{
QTextEdit::paintEvent( _event );
QPainter pnt( this );
pnt.setPen( QColor( 0, 0, 0, 0xff ));
pnt.drawRect( 0, 0, width()-1, height()-1);
}
// QPainter ( viewport() )
// QTextEdit::paintEvent at the begining of custom PaintEvent
// RESULT: works.
virtual void paintEvent(QPaintEvent *_event)
{
QTextEdit::paintEvent( _event );
QPainter pnt( viewport() );
pnt.setPen( QColor( 0, 0, 0, 0xff ));
pnt.drawRect( 0, 0, width()-1, height()-1);
}
// *** BONUS ***
// QPainter( viewport() ) or QPainter ( this )
// QTextEdit::paintEvent after QPainter() constructor.
// RESULT: Segmentation fault.
virtual void paintEvent(QPaintEvent *_event)
{
QPainter pnt( viewport() );
pnt.setPen( QColor( 0, 0, 0, 0xff ));
QTextEdit::paintEvent( _event ); // WRONG PLACE!!!
pnt.drawRect( 0, 0, width()-1, height()-1);
}
Instead of
QPainter pnt(this);
try
QPainter pnt(viewport());
pnt.setPen(QColor( 0, 0, 0, 0xff ));
pnt.drawRect(viewport()->rect());
viewport() is the paintable area and could be whats causing the issue