Clear a flag/hint in Qt - c++

I'm trying to undo Stay on Top of Windows settings on my app. I thought that by performing some bitwise operations, I will be able to undo the setting, but it is still showing on top of all the other windows.
void showKioskMode(){
//if(windowFlags()&Qt::WindowStaysOnTopHint){
if(ui->pushButton_3->text().compare("No Kiosk") == 0){
//showNormal();
Qt::WindowFlags flags = windowFlags();
flags &= ~Qt::WindowStaysOnTopHint;
setWindowFlags(flags);
ui->pushButton_3->setText("Yes Kiosk");
}
else{
//showFullScreen();
Qt::WindowFlags flags = windowFlags();
setWindowFlags(flags | Qt::WindowStaysOnTopHint);
ui->pushButton_3->setText("No Kiosk");
}
show();
}
I've checked that the if-body is being executed, but the window is still always on top of all other windows even though they have focus.

Looks like that it is a bug. The solution can be found in the following thread:
https://bugreports.qt-project.org/browse/QTBUG-30359
https://stackoverflow.com/a/2860768/1129149 - See OP's (Jake Petroules) answer.
It has a separate solution for Windows via WinAPI.

Related

Toggle Qt::WA_TranslucentBackground

I've been searching around but haven't found an answer that helps me.
As the Title says i want to toggle the attribute "Qt::WA_TranslucentBackground" on/off.
I need WA_TranslucentBackground but some users of my app reported that this doesn't work in OBS(Open Broadcaster Software) so i have to make a seperate version without the TranslucentBackground.
My Code:
void MainWindow::action_widgetMode(){
if(displayOBS ==0){
this->setAttribute(Qt::WA_TranslucentBackground,true);
}else{
this->setAttribute(Qt::WA_TranslucentBackground,false);
}
this->setWindowFlags(Qt::Widget | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
this->activateWindow();
this->setFocus();
this->show();
}
I am calling this function once upon start. And additionally on a checkbox click where i want to toggle it on/off. This code does work when i restart my application, but i want it to be immediate after the checkbox is checked/unchecked.

Enable maximize button in QWizard

I have a Windows application that is built on QWizard (which inherits from QDialog). It must have a working maximization button.
By default maximization button is not even visible. i have set it to show, using:
auto flags = windowFlags();
flags ^= Qt::WindowContextHelpButtonHint;
flags |= Qt::WindowMinMaxButtonsHint;
setWindowFlags(flags);
However, it shows up disabled (grayed out, non-responding).
How can i enable it?
This works for me:
setWindowFlags(windowFlags() | Qt::CustomizeWindowHint |
Qt::WindowMinimizeButtonHint |
Qt::WindowMaximizeButtonHint |
Qt::WindowCloseButtonHint);
According to the documentation, you have to use the Qt::CustomizeWindowHint to be able to change the individual hints on the min/max buttons.
Someone here says this solved his problem:
setWindowFlags(Qt::Window);
I believe that you'll get better results creating your own dialog, but if you really wanna do it, one way is use window styles (Windows only, not cross-plataform).
Wizard class example:
class wizard : public QWizard
{
public:
wizard() {}
~wizard() {}
protected:
bool event(QEvent *event)
{
#ifdef Q_OS_WIN /*Make this code Windows OS only*/
if (event->type() == QEvent::WinIdChange)
{
HWND hwnd = (HWND)winId();
LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
lStyle |= (WS_MINIMIZEBOX | WS_MAXIMIZEBOX); /*Enable minimize and maximize*/
SetWindowLong(hwnd, GWL_STYLE, lStyle);
}
#endif
return QWizard::event(event);
}
};
I have this:
QWizard *wizard = new QWizard(this, Qt::CustomizeWindowHint | Qt::WindowMaximizeButtonHint | Qt::Window);
wizard->setSizeGripEnabled(true);
Running Windows 10 on my dev-box, Qt 5.5.1, working for me.
One of my pages is a big QTableWidget that ends up being like an Excel sheet of some sorts (a big page to verify and edit-in-place a lot of data). Making the window resizable and let the user maximize it if they want makes it much easier to work with, instead of having to constantly scroll in a small dialog.
Normally you would say: If you need such a big window, it probably shouldn't be in a QWizard. But in this case it's really the middle of a workflow thing. A big 'verify, edit-if-needed and continue' page so it would be weird to stop the QWizard before and then having to start another one after or something.

set qt c++ mainwindow always on bottom mac osx

So I am trying to set this window/ mainwindow / application in qt to always be on the bottom (like always bottom window) (so rainmeter somehow does this with their widgets), but I can't even get mac osx to do such things.
I've tried the whole
this->setWindowFlags(Qt::WindowStaysOnBottomHint);
but without any luck. Any hints? Example code is amazing.
Got bad news and good news. The bad news is it's simply not implemented.
The good news is: as Qt is open source, you can crack it open and take a look to know that. And if there's a bug you can submit a fix. Here's the deal, in the generic code for QWidget::setWindowFlags in
qwidget.cpp:9144 you have this:
void QWidget::setWindowFlags(Qt::WindowFlags flags)
{
if (data->window_flags == flags)
return;
Q_D(QWidget);
if ((data->window_flags | flags) & Qt::Window) {
// the old type was a window and/or the new type is a window
QPoint oldPos = pos();
bool visible = isVisible();
setParent(parentWidget(), flags);
// if both types are windows or neither of them are, we restore
// the old position
if (!((data->window_flags ^ flags) & Qt::Window)
&& (visible || testAttribute(Qt::WA_Moved))) {
move(oldPos);
}
// for backward-compatibility we change Qt::WA_QuitOnClose attribute value only when the window was recreated.
d->adjustQuitOnCloseAttribute();
} else {
data->window_flags = flags;
}
}
So essentially it just sets window_flags. The mac behavior of QWidget is in qwidget_mac.mm.
And you will find no reference to Qt::WindowStaysOnBottomHint in that file. (You'll find Qt::WindowStaysOnTopHint though...)
I'll stop at saying "not possible unless you either patch Qt, or otherwise go beneath Qt".
Patching qwidget_mac.mm is left as an exercise to the reader. :-)

I can't seem to add a close button using Qt::WindowFlags

I have the following code that is called when I insert a QMdiSubWindow into a QMdiArea:
Qt::WindowFlags flags;
flags = Qt::Widget | Qt::WindowMinimizeButtonHint | Qt::WindowTitleHint;
if(closeable)
{
qDebug("Window is closeable. %x", Qt::WindowCloseButtonHint);
flags |= Qt::WindowCloseButtonHint;
}
For some reason, even when closeable is true, the closebutton won't display on the widget's titlebar.
This is the call to insert the widget into the QMdiArea.
mdi->addSubWindow(widget, flags);
Any suggestions?
I found that playing around with the window flags example included with the sdk was a lot of help when trying to get the flags correct.
C:\QtSDK\Examples\4.7\widgets\windowflags\

Notification window in Mac. With or without Qt

Qt project on Mac OS X. I need to show notification window on top without stealing a focus from any active application.
Here the widget constructor part:
setWindowFlags(
Qt::FramelessWindowHint |
Qt::WindowSystemMenuHint |
Qt::Tool |
Qt::WindowStaysOnTopHint
);
setAttribute(Qt::WA_TranslucentBackground);
Qt::WA_ShowWithoutActivating doesn't affect anything.
Is there a way to do that? I'm ready to implement the native Carbon/Cocoa solution there, but Qt is preferred.
Or maybe I'm wrong in Mac philosophy and I should notify user in a kind another manner?
Update Growl doesn't support editor line in its notifications, does it?
I did it!
#ifdef Q_OS_MAC
#include <Carbon/Carbon.h>
#endif
NotifyWindow::NotifyWindow() : QWidget(0 /* This zero is the first point */) {
setWindowFlags(
#ifdef Q_OS_MAC
Qt::SubWindow | // This type flag is the second point
#else
Qt::Tool |
#endif
Qt::FramelessWindowHint |
Qt::WindowSystemMenuHint |
Qt::WindowStaysOnTopHint
);
setAttribute(Qt::WA_TranslucentBackground);
// And this conditional block is the third point
#ifdef Q_OS_MAC
winId(); // This call creates the OS window ID itself.
// qt_mac_window_for() doesn't
int setAttr[] = {
kHIWindowBitDoesNotHide, // Shows window even when app is hidden
kHIWindowBitDoesNotCycle, // Not sure if required, but not bad
kHIWindowBitNoShadow, // Keep this if you have your own design
// with cross-platform drawn shadows
0 };
int clearAttr[] = { 0 };
HIWindowChangeAttributes(qt_mac_window_for(this), setAttr, clearAttr);
#endif
}
We get almost the same nice behavior as in Windows:
It does not stole focus on show. (Two weeks of searching over the Internet)
The controls there handle the first user click, while other windows need an extra click to activate.
When the window is being activated, the other windows of the same application, do not bubble up to the front.
And a small problem remains, but at least it has a simple workaround. Or even could be left.
Pavel,
Have you heard of Growl? Growl is a VERY impressive notification app that you can bundle and use with your application. Adium - a popular instant messaging app for OS X - uses it for all notifications.
http://growl.info/
You could implement Growl. http://growl.info/documentation/developer/
try this on mac:
setWindowFlags(windowFlags() | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
setAttribute(Qt::WA_TranslucentBackground);
setAttribute(Qt::WA_AlwaysStackOnTop);
Ive just tested these flags
Qt::FramelessWindowHint |Qt::WindowSystemMenuHint |Qt::WindowStaysOnTopHint
And
setFocusPolicy(Qt::NoFocus);
setAttribute(Qt::WA_ShowWithoutActivating,true);
Without Cocoa or Carbon code for window flags/masks.
And notifyWindow works like on Windows or Linux.