I need to create a login dialog like this
image files: eyeOn.png, eyeOff.png
Requirements:
password is shown only when we CLICK AND HOLD the eyeOn icon (even when we click and hold and drag the mouse to area outside of the dialog, the password is still shown), when we release the mouse, password is covered again.
while password is shown, the eye icon is eyeOn. While password is covered, the eye icon is eyeOff.
I have just built the layout.
QGridLayout *mainlogin = new QGridLayout();
QLabel *usernameLabel = new QLabel;
usernameLabel->setWordWrap(true);
usernameLabel->setText("Username");
mainlogin->addWidget(usernameLabel, 0, 0);
QComboBox *usernameLineEdit = new QComboBox;
usernameLineEdit->setEditable(true);
usernameLabel->setBuddy(usernameLineEdit);
mainlogin->addWidget(usernameLineEdit, 0, 1);
QLabel *capslockShow = new QLabel;
capslockShow->setWordWrap(true);
capslockShow->setText(" ");
mainlogin->addWidget(capslockShow, 1, 1);
QLabel *passwordLabel = new QLabel;
passwordLabel->setWordWrap(true);
passwordLabel->setText("Password");
mainlogin->addWidget(passwordLabel, 2, 0);
QLineEdit *passwordLineEdit = new QLineEdit;
passwordLineEdit->setEchoMode(QLineEdit::Password);
QAction *myAction = passwordLineEdit->addAction(QIcon(":/eyeOff.png"), QLineEdit::TrailingPosition);
passwordLabel->setBuddy(passwordLineEdit);
mainlogin->addWidget(passwordLineEdit, 2, 1);
What should I do next? Pls help me with code snippet.
The solution is to add a QAction to the QLineEdit, this will create a QToolButton that we can obtain from the associatedWidgets() (it will be the second widget since the first one is the one associated with clearButton). Already having the QToolButton you must use the pressed and released signal.
passwordlineedit.h
#ifndef PASSWORDLINEEDIT_H
#define PASSWORDLINEEDIT_H
#include <QAction>
#include <QLineEdit>
#include <QToolButton>
class PasswordLineEdit: public QLineEdit
{
public:
PasswordLineEdit(QWidget *parent=nullptr);
private slots:
void onPressed();
void onReleased();
protected:
void enterEvent(QEvent *event);
void leaveEvent(QEvent *event);
void focusInEvent(QFocusEvent *event);
void focusOutEvent(QFocusEvent *event);
private:
QToolButton *button;
};
#endif // PASSWORDLINEEDIT_H
passwordlineedit.cpp
#include "passwordlineedit.h"
PasswordLineEdit::PasswordLineEdit(QWidget *parent):
QLineEdit(parent)
{
setEchoMode(QLineEdit::Password);
QAction *action = addAction(QIcon(":/eyeOff"), QLineEdit::TrailingPosition);
button = qobject_cast<QToolButton *>(action->associatedWidgets().last());
button->hide();
button->setCursor(QCursor(Qt::PointingHandCursor));
connect(button, &QToolButton::pressed, this, &PasswordLineEdit::onPressed);
connect(button, &QToolButton::released, this, &PasswordLineEdit::onReleased);
}
void PasswordLineEdit::onPressed(){
QToolButton *button = qobject_cast<QToolButton *>(sender());
button->setIcon(QIcon(":/eyeOn"));
setEchoMode(QLineEdit::Normal);
}
void PasswordLineEdit::onReleased(){
QToolButton *button = qobject_cast<QToolButton *>(sender());
button->setIcon(QIcon(":/eyeOff"));
setEchoMode(QLineEdit::Password);
}
void PasswordLineEdit::enterEvent(QEvent *event){
button->show();
QLineEdit::enterEvent(event);
}
void PasswordLineEdit::leaveEvent(QEvent *event){
button->hide();
QLineEdit::leaveEvent(event);
}
void PasswordLineEdit::focusInEvent(QFocusEvent *event){
button->show();
QLineEdit::focusInEvent(event);
}
void PasswordLineEdit::focusOutEvent(QFocusEvent *event){
button->hide();
QLineEdit::focusOutEvent(event);
}
The complete example can be downloaded from the following link.
Rather than trying to make use of the QAction returned by QLineEdit::addAction you could probably use a QWidgetAction for this when combined with a suitable event filter...
class eye_spy: public QWidgetAction {
using super = QWidgetAction;
public:
explicit eye_spy (QLineEdit *control, QWidget *parent = nullptr)
: super(parent)
, m_control(control)
, m_on(":/eyeOn")
, m_off(":/eyeOff")
, m_pixmap_size(50, 50)
{
m_label.setScaledContents(true);
m_control->setEchoMode(QLineEdit::Password);
m_label.setPixmap(m_off.pixmap(m_pixmap_size));
m_label.installEventFilter(this);
setDefaultWidget(&m_label);
}
protected:
virtual bool eventFilter (QObject *obj, QEvent *event) override
{
if (event->type() == QEvent::MouseButtonPress) {
m_control->setEchoMode(QLineEdit::Normal);
m_label.setPixmap(m_on.pixmap(m_pixmap_size));
} else if (event->type() == QEvent::MouseButtonRelease) {
m_control->setEchoMode(QLineEdit::Password);
m_label.setPixmap(m_off.pixmap(m_pixmap_size));
}
return(super::eventFilter(obj, event));
}
private:
QLineEdit *m_control;
QLabel m_label;
QIcon m_on;
QIcon m_off;
QSize m_pixmap_size;
};
Now, rather than...
QAction *myAction = passwordLineEdit->addAction(QIcon(":/eyeOff.png"), QLineEdit::TrailingPosition);
Use...
eye_spy eye_spy(passwordLineEdit);
passwordLineEdit->addAction(&eye_spy, QLineEdit::TrailingPosition);
Seems to provide the desired behaviour.
Related
My problem was right-clicking the Qpushbutton it will show the items in it. how can we write this code using Qt C++? before I kept a combo box for the menu but now I need to keep the pushbutton Rightclick event to open the items?
""""""".h"""""""""
class MainWindow: public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
Bc *open;
Rt *open1;
Mt * open2;
//QRightclickbutton *open3;
//QRightClickButton(QWidget *parent = 0);
~MainWindow();
//protected:
//void mousePressEvent(QMouseEvent *e);
signals:
void rightClicked();
protected:
// void mousePressEvent(QMouseEvent * event);
void pushbutton(QWidget *parent);
void mousePressEvent(QMouseEvent *e);
private slots:
//bool eventFilter(QObject *obj, QEvent *e);
void on_pb1_clicked();
void on_pb2_clicked();
void on_pb3_clicked();
void on_pb4_clicked();
// void on_pushButton_clicked();
// void on_pushButton_clicked(bool checked);
void on_pb_rightclicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H`
""Mainwindow.cpp""
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setWindowTitle("Unical Project Title");
QMenu *menu = new QMenu(this);
menu->addAction("BC");
menu->addAction("RT");
menu->addAction("MT");
ui-> pb->setMenu(menu);
// connect(ui->pushButton, SIGNAL(Rightclicked), this, SLOT(play()));
// ui->pushButton->viewport()-> installEventFilter(this);
open = new Bc;
open1= new Rt;
open2= new Mt;
QObject *w = new QObject;
// QString *select = new QString;
ui->device0->addItem("Set as ");
ui->device0->addItem("BC");
ui->device0->addItem("RT");
ui->device0->addItem("MT");
//QObject::connect(ui->device0, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
// open->show();
ui->device1->addItem("Set as");
ui->device1->addItem("BC");
ui->device1->addItem("RT");
ui->device1->addItem("MT");
ui->device2->addItem("Set as");
ui->device2->addItem("BC");
ui->device2->addItem("RT");
ui->device2->addItem("MT");
ui->device3->addItem("Set as");
ui->device3->addItem("BC");
ui->device3->addItem("RT");
ui->device3->addItem("MT");
// int row= 7;
// int column= 2;
for (int row =0; row<=ui->tablewidget->rowCount(); row++)
{
QCheckBox * cb = new QCheckBox(this);
cb->setCheckState(Qt::Checked);
QWidget *w =new QWidget ();
QHBoxLayout *hLayout =new QHBoxLayout();
hLayout->addWidget(cb);
hLayout->setMargin(0);
hLayout->setAlignment(cb,Qt::AlignCenter);
w->setLayout(hLayout);
ui->tablewidget->setCellWidget(row,2,w);
}
}
MainWindow::~MainWindow()
{
delete UI;
}
void MainWindow::on_pb1_clicked()
{
ui->device0->currentText();
if(ui->device0->currentText() == "BC")
{
QObject::connect(ui->device0, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
open->show();
}
if (ui->device0->currentText() == "RT")
{
QObject::connect(ui->device0, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
open1->show();
}
if (ui->device0->currentText() == "MT")
{
QObject::connect(ui->device0, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
open2->show();
}
}
void MainWindow::on_pb2_clicked()
{
ui->device1->currentText();
if(ui->device1->currentText() == "BC")
{
QObject::connect(ui->device1, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
open->show();
}
if (ui->device1->currentText() == "RT")
{
QObject::connect(ui->device1, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
open1->show();
}
if (ui->device1->currentText() == "MT")
{
QObject::connect(ui->device1, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
open2->show();
}
}
void MainWindow::on_pb3_clicked()
{
ui->device2->currentText();
if(ui->device2->currentText() == "BC")
{
QObject::connect(ui->device2, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
open->show();
}
if (ui->device2->currentText() == "RT")
{
QObject::connect(ui->device2, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
open1->show();
}
if (ui->device2->currentText() == "MT")
{
QObject::connect(ui->device2, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
open2->show();
}
}
void MainWindow::on_pb4_clicked()
{
ui->device3->currentText();
if(ui->device3->currentText() == "BC")
{
QObject::connect(ui->device3, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
open->show();
}
if (ui->device3->currentText() == "RT")
{
QObject::connect(ui->device0, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
open1->show();
}
if (ui->device3->currentText() == "MT")
{
QObject::connect(ui->device3, SIGNAL(currentTextChanged(QString)),this,SLOT(setText(QString)));
open2->show();
}
}
//void MainWindow::on_pushButton_clicked(bool checked)
//{
// QMouseEvent *button= new QMouseEvent(this);
// ui->pushButton->button;
// connect(button, SIGNAL(rightClicked()), this, SLOT(()));
// qDebug()<<"right clicked";
//}
void pushbutton ::on_pb_rightclicked()
{
connect(ui->pushButton, SIGNAL(rightClicked),this, SLOT (menuBar(show())));
}
//void pushbutton::on_pb_clicked()
//{
//}
what I want is while Rightclick the Qpushbutton it shows the items in it and please help me to do this. thank you
You could use a custom context menu for the QPushButton.
First, you will need to assign the button context menu policy. So when you initialize your MainWindow, you should also:
ui->pushButton->setContextMenuPolicy(Qt::CustomContextMenu);
Then create a slot for when the custom context menu is requested (when the button is right-clicked):
//Your .h
private slots:
void on_pushButton_customContextMenuRequested(const QPoint &pos);
// Your .cpp
void MainWindow::on_pushButton_customContextMenuRequested(const QPoint &pos)
{
QMenu contextMenu(tr("Context menu"), this);
QAction action1("BC", this);
connect(&action1, &QAction::triggered,
[]{qDebug() << "User selected BC";});
contextMenu.addAction(&action1);
QAction action2("RT", this);
connect(&action2, &QAction::triggered,
[]{qDebug() << "User selected RT";});
contextMenu.addAction(&action2);
QAction action3("MT", this);
connect(&action3, &QAction::triggered,
[]{qDebug() << "User selected MT";});
contextMenu.addAction(&action3);
contextMenu.exec(mapToGlobal(pos));
}
I'm not sure what you want to have done when the user selects an item from the context menu, so the above uses a lambda function when each action is triggered. Alternately you could use a traditional signal/slot connection.
In the future, please try to include only the code for a MRE
I have QButtonGroup in which i have added 5 QPushButton and have set the id for all QPushButton. Now when id is 2, i want to setSize of id 1 and 3 to (100,100).
QButtonGroup *button = new QButtonGroup;
button.addButton(button1,1);
button.addButton(button2,2);
..
..
button.addButton(button5,5);
Now i want when button2 has focus then i want to set its size to (150,150) and button1 and button3 size to (100,100).
I got it,so here is what you need to do:
In my Dlg.h
class MyPushButton : public QPushButton
{
public:
MyPushButton(QString ButtonName, QWidget *parent);
void focusInEvent(QFocusEvent* event);
void focusOutEvent(QFocusEvent* event);
};
In my Dlg.cpp:
MyPushButton::MyPushButton(QString ButtonName, QWidget *parent)
:QPushButton(ButtonName,parent)
{
}
void MyPushButton::focusInEvent(QFocusEvent* event)
{
this->setMinimumHeight(150);
this->setMinimumWidth(150);
}
void MyPushButton::focusOutEvent(QFocusEvent* event)
{
this->setMinimumHeight(100);
this->setMinimumWidth(100);
}
You dont need QButtonGroup.Now all you need to do is use "MyPushButton" class and set the default height and width of the buttons to 100 *100.Let me know if you have any doubts.
MyMainWindow.cpp ,its ctor:
MyMainWindow::MyMainWindow(QWidget *parent, Qt::WFlags flags)
:QMainWindow(parent, flags)
{
ui.setupUi(this);
this->setWindowTitle(QString::fromUtf8("MainWindow"));
this->resize(250, 250);
QWidget *centralWidget = new QWidget(this);
//Create QPushButtons
button1 = new MyPushButton("Button 1" , centralWidget);
button1->setMinimumHeight(100);
button1->setMinimumWidth(100);
button2 = new MyPushButton("Button 2" , centralWidget);
button2->setMinimumHeight(100);
button2->setMinimumWidth(100);
button3 = new MyPushButton("Button 3" , centralWidget);
button3->setMinimumHeight(100);
button3->setMinimumWidth(100);
button4 = new MyPushButton("Button 4" , centralWidget);
button4->setMinimumHeight(100);
button4->setMinimumWidth(100);
QHBoxLayout* layout = new QHBoxLayout(centralWidget);
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
layout->addWidget(button4);
layout->setSizeConstraint(QLayout::SetNoConstraint);
this->setCentralWidget(centralWidget);
}
In MyMainWindow.h
class MyMainWindow: public QMainWindow
{
Q_OBJECT
public:
MyMainWindow(QWidget *parent = 0, Qt::WFlags flags = 0);
~MyMainWindow();
public slots:
void FileNew(int i);
void keyReleaseEvent(QKeyEvent *e);
private:
Ui::StClass ui;
MyPushButton* button1;
MyPushButton* button2;
MyPushButton* button3;
MyPushButton* button4;
};
Is it possible to show minimum, maximum and current selected value of QSlider? Of course I can use labels to display this, but I think there must be such possibility in QSlider
You have two options..
1) as being mentioned in comments - sub - class
2) add as many QLabel's as you like with QSlider as a parent, install eventHandler() on QSlider to catch resize event to proper position them, and obviously handle scroll events, so you can update them... So labels will just float on top of QSlider
Here is my quick implementation of a fancy slider which subclass qslider to displays the current value just below the slider handle into a tooltip.
Header
#ifndef FANCYSLIDER_H
#define FANCYSLIDER_H
#include <QSlider>
class FancySlider : public QSlider
{
Q_OBJECT
public:
explicit FancySlider(QWidget *parent = 0);
explicit FancySlider(Qt::Orientation orientation, QWidget *parent = 0);
protected:
virtual void sliderChange(SliderChange change);
};
#endif // FANCYSLIDER_H
Cpp
#include "FancySlider.h"
#include <QStyleOptionSlider>
#include <QToolTip>
FancySlider::FancySlider(QWidget * parent)
: QSlider(parent)
{
}
FancySlider::FancySlider(Qt::Orientation orientation, QWidget * parent)
: QSlider(orientation, parent)
{
}
void FancySlider::sliderChange(QAbstractSlider::SliderChange change)
{
QSlider::sliderChange(change);
if (change == QAbstractSlider::SliderValueChange )
{
QStyleOptionSlider opt;
initStyleOption(&opt);
QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this);
QPoint bottomRightCorner = sr.bottomLeft();
QToolTip::showText(mapToGlobal( QPoint( bottomRightCorner.x(), bottomRightCorner.y() ) ), QString::number(value()), this);
}
}
Here is my implementation, without subclassing. Instanciate a slider with a label at right, showing the current value of slider :
QWidget *tmpW1 = new QWidget(this);
QHBoxLayout *tmpH1 = new QHBoxLayout(this);
QLabel *tmpLabel = new QLabel("0");
QSlider *tmpSlider = new QSlider(Qt::Horizontal, this);
tmpSlider->setMinimum(0);
tmpSlider->setMaximum(10);
tmpSlider->setValue(5);
tmpH1->addWidget(tmpSlider);
tmpH1->addWidget(tmpLabel);
tmpW1->setLayout(tmpH1);
QObject::connect(tmpSlider, &QSlider::valueChanged, this, [=] () {
tmpLabel->setText(QString::number(tmpSlider->value()));
});
I have a a QWidgetAction which holds a QWidget composed of a QLineEdit and a QPushButton. Once the user press the button the QWidgetAction call the trigger slot.
Now I have a QMenu which I activate with exec. The problem is that even though trigger is called (I've connected it to a print function as well to check) the menu won't close.
Regular QActions works well.
Any idea why?
P.S. Googling this issue I came across people with the same problem, but no solutions.
Years old question, but still I have an answer, hope it helps anybody!
I will describe my complete solution which not only hides the menu but also manages the visual representation.
QWidgetAction subclass: MyClass.h
class MyClass : public QWidgetAction {
Q_OBJECT
public:
MyClass(QObject* parent);
bool eventFilter(QObject*, QEvent*) override;
signals:
void mouseInside();
void mouseOutside();
protected:
QWidget* createWidget(QWidget* parent) override;
private:
QWidget* w;
QWidget* border;
QFormLayout *form;
QHBoxLayout *mainLayout;
}
QWidgetAction subclass MyClass.cpp
QWidget* MyClass::createWidget(QWidget* parent) {
w = new QWidget(parent);
border = new QWidget(parent);
mainLayout = new QHBoxLayout(w);
layout = new QFormLayout();
border->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Maximum));
border->setMaximumWidth(10);
border->setMinimumWidth(10);
border->setMaximumHeight(1000); //Anything will do but it needs a height
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(0);
w->setLayout(mainLayout);
mainLayout->addWidget(border);
mainLayout->addLayout(layout);
layout->setContentsMargins(6, 11, 11, 11);
layout->setSpacing(6);
// Insert your widgets here, I used a QFormLayout
QLineEdit *l = new QLineEdit(w);
form->addRow("Test", l);
// I added a button to accept input
QPushButton* b = new QPushButton("Send", w);
connect(b, SIGNAL(clicked()), this, SLOT(trigger()));
layout->addWidget(b);
w->installEventFilter(this); // This is to avoid non button clicks to close the menu
return w;
}
bool MyClass::eventFilter(QObject*, QEvent* ev) {
if (ev->type() == QEvent::MouseButtonPress
|| ev->type() == QEvent::MouseButtonDblClick
|| ev->type() == QEvent::MouseButtonRelease) {
return true;
} else if (ev->type() == QEvent::Enter) {
border->setStyleSheet("background-color: #90c8f6;");
emit mouseInside();
} else if (ev->type() == QEvent::Leave) {
border->setStyleSheet("");
emit mouseOutside();
}
return false;
}
Finally to insert the QWidgetAction in a menu, in your code add the following:
QMenu *m = new QMenu(this);
MyClass *item = new MyClass(m);
connect(item, &QAction::triggered, [=] { m->hide(); YOUR CODE HERE}); // Add your action here
// This is to give a visual cue to your item, while deselecting the stuck
// action which was previously selected
connect(item, &MyClass::mouseInside, [=] { m->setActiveAction(nullptr); });
ui->yourButton->setMenu(m);
m->addAction(item);
I'm new to Qt C++. I downloaded the latest windows version, did some tutorials and its great.
I saw some styling options that the Qt framework has and its great, but now I need to build my application that its main windows (form) it designed/skinned with image without the rectangle borders (borderless?).
How can I do it with Qt?
If your looking for some advanced styling in the shape of a widget, maybe this example will help you:
Shaped Clock Example
Or maybe you're simply looking for this kind of flag: Qt::CustomizeWindowHint or simply Qt::FramelessWindowHint.
I created a small example, of how to create VS2013 like frameless window in Qt5:
You can get the complete sources here: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle
Otherwise here a code overview of how to embed the "main" mainwindow into the "frameless" window. Also you can see how to add titlebar, buttons and do maximize, resize and move of the frameless window.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets>
/*
place your QMainWindow code here
*/
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
/*
this class is to add frameless window supoort and do all the stuff with titlebar and buttons
*/
class BorderlessMainWindow: public QMainWindow
{
Q_OBJECT
public:
explicit BorderlessMainWindow(QWidget *parent = 0);
~BorderlessMainWindow() {}
protected:
void mouseMoveEvent(QMouseEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
void mouseDoubleClickEvent(QMouseEvent *event);
private slots:
void slot_minimized();
void slot_restored();
void slot_maximized();
void slot_closed();
private:
MainWindow *mMainWindow;
QWidget *mTitlebarWidget;
QLabel *mWindowTitle;
QPushButton *mMinimizeButton;
QPushButton *mRestoreButton;
QPushButton *mMaximizeButton;
QPushButton *mCloseButton;
QPoint mLastMousePosition;
bool mMoving;
bool mMaximized;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
/*
frameless window class: it adds the MainWindow class inside the centralWidget
*/
BorderlessMainWindow::BorderlessMainWindow(QWidget *parent) : QMainWindow(parent, Qt::CustomizeWindowHint ) {
setObjectName("borderlessMainWindow");
setWindowFlags(Qt::FramelessWindowHint| Qt::WindowSystemMenuHint);
// to fix taskbar minimize feature
setWindowFlags(windowFlags() | Qt::WindowMinimizeButtonHint);
mMainWindow = new MainWindow(this);
setWindowTitle(mMainWindow->windowTitle());
QVBoxLayout *verticalLayout = new QVBoxLayout();
verticalLayout->setSpacing(0);
verticalLayout->setMargin(1);
QHBoxLayout *horizontalLayout = new QHBoxLayout();
horizontalLayout->setSpacing(0);
horizontalLayout->setMargin(0);
mTitlebarWidget = new QWidget(this);
mTitlebarWidget->setObjectName("titlebarWidget");
mTitlebarWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
mTitlebarWidget->setLayout(horizontalLayout);
mMinimizeButton = new QPushButton(mTitlebarWidget);
mMinimizeButton->setObjectName("minimizeButton");
connect(mMinimizeButton, SIGNAL(clicked()), this, SLOT(slot_minimized()));
mRestoreButton = new QPushButton(mTitlebarWidget);
mRestoreButton->setObjectName("restoreButton");
mRestoreButton->setVisible(false);
connect(mRestoreButton, SIGNAL(clicked()), this, SLOT(slot_restored()));
mMaximizeButton = new QPushButton(mTitlebarWidget);
mMaximizeButton->setObjectName("maximizeButton");
connect(mMaximizeButton, SIGNAL(clicked()), this, SLOT(slot_maximized()));
mCloseButton = new QPushButton(mTitlebarWidget);
mCloseButton->setObjectName("closeButton");
connect(mCloseButton, SIGNAL(clicked()), this, SLOT(slot_closed()));
mWindowTitle = new QLabel(mTitlebarWidget);
mWindowTitle->setObjectName("windowTitle");
mWindowTitle->setText(windowTitle());
horizontalLayout->addWidget(mWindowTitle);
horizontalLayout->addStretch(1);
horizontalLayout->addWidget(mMinimizeButton);
horizontalLayout->addWidget(mRestoreButton);
horizontalLayout->addWidget(mMaximizeButton);
horizontalLayout->addWidget(mCloseButton);
verticalLayout->addWidget(mTitlebarWidget);
verticalLayout->addWidget(mMainWindow);
QWidget *centralWidget = new QWidget(this);
centralWidget->setObjectName("centralWidget");
centralWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
centralWidget->setLayout(verticalLayout);
setCentralWidget(centralWidget);
}
void BorderlessMainWindow::mousePressEvent(QMouseEvent* event) {
if (!mTitlebarWidget->underMouse() && !mWindowTitle->underMouse())
return;
if(event->button() == Qt::LeftButton) {
mMoving = true;
mLastMousePosition = event->pos();
}
}
void BorderlessMainWindow::mouseMoveEvent(QMouseEvent* event) {
if (!mTitlebarWidget->underMouse() && !mWindowTitle->underMouse())
return;
if( event->buttons().testFlag(Qt::LeftButton) && mMoving) {
this->move(this->pos() + (event->pos() - mLastMousePosition));
}
}
void BorderlessMainWindow::mouseReleaseEvent(QMouseEvent* event) {
if (!mTitlebarWidget->underMouse() && !mWindowTitle->underMouse())
return;
if(event->button() == Qt::LeftButton) {
mMoving = false;
}
}
void BorderlessMainWindow::mouseDoubleClickEvent(QMouseEvent *event) {
Q_UNUSED(event);
if (!mTitlebarWidget->underMouse() && !mWindowTitle->underMouse())
return;
mMaximized = !mMaximized;
if (mMaximized) {
slot_maximized();
} else {
slot_restored();
}
}
void BorderlessMainWindow::slot_minimized() {
setWindowState(Qt::WindowMinimized);
}
void BorderlessMainWindow::slot_restored() {
mRestoreButton->setVisible(false);
mMaximizeButton->setVisible(true);
setWindowState(Qt::WindowNoState);
setStyleSheet("#borderlessMainWindow{border:1px solid palette(highlight);}");
}
void BorderlessMainWindow::slot_maximized() {
mRestoreButton->setVisible(true);
mMaximizeButton->setVisible(false);
setWindowState(Qt::WindowMaximized);
setStyleSheet("#borderlessMainWindow{border:1px solid palette(base);}");
}
void BorderlessMainWindow::slot_closed() {
close();
}
/*
MainWindow class: put all your code here
*/
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent, Qt::FramelessWindowHint), ui(new Ui::MainWindow) {
ui->setupUi(this);
statusBar()->setSizeGripEnabled(true);
}
MainWindow::~MainWindow() {
delete ui;
}
There is a sample application in your Qt directory: examples/widgets/windowsflags.
I ran into this myself and figured it out after some time. Check out https://github.com/ianbannerman/TrueFramelessWindow for sample code for both Windows & macOS.
Qt::FramelessWindowHint sacrifices resizing and min/max/close, so is probably not what mot people are looking for.