设置无边框窗口

  1. 设置无边框窗口,窗口不可移动或者拖动更改大小;同时增加最大化最小化按钮,效果就是点击Windows底部任务栏的应用程序图标可以对应用程序最大化和最小化
// Qt::WindowMinMaxButtonsHint表示增加最大化最小化按钮
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);

  1. 无边框窗口移动:重写鼠标按下,移动事件
void MainWindow::mousePressEvent(QMouseEvent* event)
{
    mouse_pos = event->globalPos();         // 记录鼠标按下时的全局屏幕坐标
    window_pos = this->pos();               // 记录窗口当前的左上角坐标
    diff_pos = mouse_pos - window_pos;      // 计算鼠标相对于窗口左上角的偏移量
}

void MainWindow::mouseMoveEvent(QMouseEvent* event)
{
    QPoint pos = event->globalPos();
    this->move(pos - diff_pos);             // 更新窗口位置
}

设置窗口阴影

  1. 需要两个窗口,底层窗口设置背景透明,顶层窗口设置背景色
  2. 为顶层窗口设置阴影

设置窗口圆角

1.方式1
  1. 设置窗口的一些属性:
// 设置窗口背景为透明
setAttribute(Qt::WA_TranslucentBackground); 
// 去除窗口边框,保留了最小化和最大化按钮
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);
  1. 重写paintEvent方法:
void MainWindow::paintEvent(QPaintEvent* event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);  // 反锯齿;
    painter.setBrush(QBrush(QColor(255, 255, 255)));
    painter.setPen(Qt::transparent);
    QRect rect = this->rect();
    painter.drawRoundedRect(rect, 15, 15);          //设置窗口圆角 15px
}
2.方式2
MainWindow::MainWindow(QWidget *parent)
    : QWidget(parent)
{
    setAttribute(Qt::WA_TranslucentBackground);  //设置窗口背景透明
    setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint);  //去掉窗口边框

    this->setStyleSheet("QWidget{background-color:#FFFFFF;border-radius:30px;}");
    
}

void MainWindow::paintEvent(QPaintEvent*)
{
    QStyleOption opt;
    // 从当前Widget获取必要的样式信息
    opt.init(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

上下文菜单

1.菜单策略为Qt::DefaultContextMenu

这种策略下只要满足条件,QWidget::contextMenuEvent方法将会自动被调用

  1. 继承自QWidget的类需要重写contextMenuEvent方法。
void Widget::contextMenuEvent(QContextMenuEvent* event)
{
    if (m_pMenu) {
        m_pMenu->exec(event->globalPos());  // 使用事件提供的坐标
    }
    event->accept();                        // 标记事件已处理
}
  1. 构造函数中初始化QMenu对象,包括信号和槽,动作等
  2. 构造函数中设置菜单策略为Qt::DefaultContextMenu:
this->setContextMenuPolicy(Qt::DefaultContextMenu);
2.菜单策略为Qt::CustomContextMenu

这种策略下只要满足相应的条件就会发送QWidget::customContextMenuRequested信号

  1. 构造函数中初始化QMenu对象,包括信号和槽,动作等
  2. 构造函数中设置菜单策略为Qt::CustomContextMenu:
this->setContextMenuPolicy(Qt::CustomContextMenu);
  1. 构造函数中连接信号和槽,槽函数处理QWidget::customContextMenuRequested信号
  2. 处理QWidget::customContextMenuRequested信号的槽函数实现,示例如下
void MainWindow::on_PopupRightMenu(const QPoint& pos)
{
    QListWidgetItem* pItem = ui.listWidget->itemAt(pos);
    // 点击QListWidgetItem才会弹出上下文菜单
    if (!pItem)
    {
        return;
    }

    m_pRightMenu->exec(QCursor::pos());
}

窗口常用属性

  1. 禁止父窗口影响子窗口样式:
// WA_StyledBackground:Indicates the widget should be drawn using a styled background
setAttribute(Qt::WA_StyledBackground);
  1. 设置窗口为无边框窗口:
setWindowFlags(Qt::FramelessWindowHint);
  1. 设置窗口背景为透明:
setAttribute(Qt::WA_TranslucentBackground); 

点击按钮弹出菜单

  1. 在构造函数中初始化QMenu菜单对象
  2. 为QPushButton设置菜单

QSS加载方式

  1. 使用Qt Designer打开ui设计文件,在属性窗口中为控件styleSheet属性设置样式值
  2. 使用R字符串定义样式,代码中调用setStyleSheet方法为控件设置样式,示例如下
QString lineEditQss = R"(
        QLineEdit{
            background-color:red;
        })";
ui->lineEdit->setStyleSheet(lineEditQss);
  1. 将样式的定义编写在单独的头文件中或者qss文件中,然后加入到资源文件qrc中

位置关系

绝对位置
  1. 鼠标绝对位置:对于QMousePressEvent的参数event,event->globalPos()表示相对于桌面原点的位置,为绝对位置
  2. 按钮绝对位置:以按钮为例,ui->pushButton->mapToGlobal(QPoint(0,0))表示按钮相对于桌面左上角的绝对位置
相对位置
  1. 鼠标相对位置:对于QMousePressEvent的参数event, event->pos()表示鼠标相对于应用程序的位置
  2. 按钮相对位置:以按钮为例,ui->pushButton->pos()表示按钮相对于应用程序的位置