Create a popup in Qt without shadow

I am developing an application using Qt 4.5 (under Windows Vista, but I want it to be cross-platform). I am using C ++

I would like to create a popup containing a QLineEdit widget, with a function that when a user interacts with a QLineEdit widget, the popup does not activate (the main application window remains active).

Creating a window (widget) with Qt :: Popup | Qt :: Window flags give me exactly what I want, except that I do not want the shadow shadow border effect to be provided. I want a borderless window. Note that the Qt :: FramelessWindowHint flag does not achieve this.

Does anyone have any clues?

Further clarification: Below is a fragment of a simple test application in which a window with a button is created. When the button is pressed, a pop-up window is displayed, and the user can enter QLineEdit in the field. When the user does this, the main window remains activated:

http://howlettresearch.com/popup_img_1.png

However, pay attention to the shadow frame in the pop-up window (I could not get rid of this).

For comparison, creating a window, as in a numbered line, allows you to create a pop-up style window without a shadow, but when the user clicks on QLineEdit in the pop-up window, the main window is no longer active. You can say that the shadow in the main window has changed.

http://howlettresearch.com/popup_img_2.png

I'm really after a popup that behaves as if it is part of the main window. As a side note, the popup disappears when I click on it, but this is almost the behavior that I want, and I can work with this and grabMouse etc., to do what I want ... provided that I I can get rid of this shadow!

PopupTest::PopupTest(QWidget *parent, Qt::WFlags flags) : QMainWindow(parent, flags) { QPushButton* pb = new QPushButton("test button"); setCentralWidget(pb); QObject::connect(pb, SIGNAL(clicked()), this, SLOT(handleClick())); } void PopupTest::handleClick() { //QFrame* popup1 = new QFrame(this, Qt::Tool | Qt::Window | Qt::FramelessWindowHint); QFrame* popup1 = new QFrame(this, Qt::Popup | Qt::Window ); popup1->resize(150,100); QLineEdit *tmpE = new QLineEdit( popup1 ); connect( tmpE, SIGNAL( returnPressed() ), popup1, SLOT( hide() ) ); tmpE->setGeometry(10,10, 130, 30); tmpE->setFocus(); popup1->show(); } PopupTest::~PopupTest() { } 
+6
qt popup popupwindow
source share
3 answers

I developed a solution to a previously posed question.

Firstly, a pop-up widget can be created by getting a QWidget with Qt :: Window | Qt :: FramelessWindowHint. I really hacked qwidget_win.cpp to ensure that my window has the same style and extended style as the Popup control provided by WPF (0x96000000 and 0x08000088 respectively) as defined by Spy ++, however I don't think that it matters.

Setting the window style does not resolve the window activation problem. The key to this is to intercept Windows messages that tell the main window that the non-client area should be updated (WM_NCACTIVATE message). This can be done by providing a custom implementation of QApplication :: winEventFilter (MSG * msg, long * result).

Unfortunately, simply inactivating WM_ NCACTIVATE messages is not enough, because it seems to prevent the transmission of WM_ ACTIVATE and other messages that would otherwise be generated from sending to a popup window. To solve this problem, I have proof that I am working on creating the necessary window messages in winEventFilter after finding the corresponding WM_NCACTIVATE message.

There are some details here to make sure it is reliable (WM_ACTIVATEAPP interception comes to mind) and then completes it into something nice and reusable.

All this, of course, is specific to Windows, it is interesting to see if there are problems in Linux.

All this is a little painful. I hope I haven’t missed anything obvious ...

+6
source share

Try this weird code below (tested on Qt v5. *):

 //BasePopup.h #ifndef BASEPOPUP_H #define BASEPOPUP_H #include <QFrame> class BasePopup : public QFrame { Q_OBJECT public: explicit BasePopup(QWidget* parent = nullptr); }; #endif // BASEPOPUP_H 


 //BasePopup.cpp #include "BasePopup.h" BasePopup::BasePopup(QWidget *parent) : QFrame(parent, Qt::Window | Qt::FramelessWindowHint) { /*setAttribute(Qt::WA_TranslucentBackground);*/ /* if need transparent background; set this attribute in another place create window with black background */ show(); // must be, if not system shadow occur :) I don't know why setWindowFlags(Qt::Popup | Qt::FramelessWindowHint); show(); //---------------------- //yours code here //---------------------- } 

Only works with calling sequence methods. If something changes, we have a pop-up window. (Magic :)))))

Edit

I found this Qt::NoDropShadowWindowHint in the Qt::WindowFlags (Qt v5.3). What appeared in one version of Qt v5. *. With this flag above, the code should look something like this.

 //BasePopup.cpp #include "BasePopup.h" BasePopup::BasePopup(QWidget *parent) : QFrame(parent, Qt::Popup | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint) { //---------------------- //yours code here //---------------------- } 

I have not tested it yet, but I think it should work.

+3
source share

I think the shadow that you see is related to the Windows theme that you are using. I use the Windows Classic theme here and I do not see any shadows :)

In any case, what if you include textChanged () SIGNAL QLineEdit in a custom action that restores the focus of the main window? Something like:

 void PopupTest::handleClick() { QFrame* popup1 = new QFrame(this, Qt::Tool | Qt::Window | Qt::FramelessWindowHint); popup1->resize(150,100); QLineEdit *tmpE = new QLineEdit( popup1 ); connect( tmpE, SIGNAL( returnPressed() ), popup1, SLOT( hide() ) ); connect( tmpE, SIGNAL( textChanged(const QString&)), this, SLOT( setActive() ) ); tmpE->setGeometry(10,10, 130, 30); tmpE->setFocus(); popup1->show(); } void MainWindow::setActive() { this->activateWindow(); } 

You will need to create a slot called setActive (), and you should also put a QLineEdit in your class header so that you can do something like the setActive () function:

 tmpE->setFocus(); 

to restore focus on QLineEdit.

+2
source share

All Articles