qt自定义含有拖动功能的窗口在点击窗口的下拉列表时窗口移动

提要

自定义的弹出窗口,窗口可以实现按下鼠标拖动,鼠标释放停止拖动,窗口中含有子控件,下拉列表,在点击下拉列表时窗口移动。

解决方法

因为点击下拉列表的时候,触发了窗口的移动事件,所以添加下拉列表的事件过滤。
下面附上实现代码:

ui->comboBoxReso->installEventFilter(this);

bool ResolutionDialog::eventFilter(QObject *obj, QEvent *event)
{
    if(obj == ui->comboBoxReso){
        if(event->type() == QEvent::MouseMove){
            return true;
        }
    }
    return QDialog::eventFilter(obj,event);
}

ui文件的结构如下:
在这里插入图片描述
在构造函数种安装控件的事件过滤器。然后重写过滤事件。
完整的代码如下:
resolutiondialog.h

#ifndef RESOLUTIONDIALOG_H
#define RESOLUTIONDIALOG_H

#include <QDialog>
#include "datastruct.h"

/***********类功能描述:分辨率设置对话框************/
namespace Ui {
class ResolutionDialog;
}

class ResolutionDialog : public QDialog
{
    Q_OBJECT

public:
    explicit ResolutionDialog(QWidget *parent = nullptr);
    ~ResolutionDialog();

    //初始化
    void initResolutions();//初始化下拉列表的分辨率

protected:
    bool eventFilter(QObject *obj, QEvent *event);//过滤事件,过滤掉下拉列表的点击事件
    void mousePressEvent(QMouseEvent *event);//鼠标点击
    void mouseMoveEvent(QMouseEvent *event);//鼠标移动事件
    void mouseReleaseEvent(QMouseEvent *event);//鼠标释放事件
signals:
    void sigEveryResolution(stuReso &stuResolution);//发送每块屏的屏幕分辨率
public slots:
    void onSetRowColSlot(int row,int col);//设置SpinBox的行列信息
private slots:
    void on_closeBtn_clicked();//关闭按钮
    void on_confirmBtn_clicked();//确定按钮
    void on_cancelBtn_clicked();//取消按钮

private:
    Ui::ResolutionDialog *ui;
    QPoint              m_offPos;//鼠标点击点与窗口左上角之间的距离
};

#endif // RESOLUTIONDIALOG_H

resolutiondialog.cpp

#include "resolutiondialog.h"
#include "ui_resolutiondialog.h"
#include <QStyledItemDelegate>

ResolutionDialog::ResolutionDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ResolutionDialog)
{
    ui->setupUi(this);

    initResolutions();
    QStyledItemDelegate *delegate = new QStyledItemDelegate();
    ui->comboBoxReso->setItemDelegate(delegate);
    ui->comboBoxReso->installEventFilter(this);

    setWindowFlag(Qt::FramelessWindowHint);
    setAttribute(Qt::WA_TranslucentBackground);
}

ResolutionDialog::~ResolutionDialog()
{
    delete ui;
}

void ResolutionDialog::initResolutions()
{
    QList<QString> strList;
    strList.append("3840x2160");
    strList.append("1920x1080");
    strList.append("1680x1050");
    strList.append("1600x900");
    strList.append("1440x900");
    strList.append("1366x768");
    strList.append("1280x1024");

    QStringList strResoList(strList);
    ui->comboBoxReso->addItems(strResoList);
}

bool ResolutionDialog::eventFilter(QObject *obj, QEvent *event)
{
    if(obj == ui->comboBoxReso){
        if(event->type() == QEvent::MouseMove){
            return true;
        }
    }
    return QDialog::eventFilter(obj,event);
}

void ResolutionDialog::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        QPoint startPos = event->globalPos();
        m_offPos = startPos - geometry().topLeft();
    }
    QDialog::mousePressEvent(event);
}

void ResolutionDialog::mouseMoveEvent(QMouseEvent *event)
{
    if (event->buttons() == Qt::LeftButton) {
        QPoint endPos = event->globalPos();
        move(endPos - m_offPos);
    }
    QDialog::mouseMoveEvent(event);
}

void ResolutionDialog::mouseReleaseEvent(QMouseEvent *event)
{
    QDialog::mouseReleaseEvent(event);
}

void ResolutionDialog::onSetRowColSlot(int row, int col)
{
    ui->spinBoxRow->setRange(0,row-1);
    ui->spinBoxCol->setRange(0,col-1);
}

void ResolutionDialog::on_closeBtn_clicked()
{
    close();
}

void ResolutionDialog::on_confirmBtn_clicked()
{
    stuReso tempReso;
    tempReso.row = ui->spinBoxRow->value();
    tempReso.col = ui->spinBoxCol->value();
    QString strTemp = ui->comboBoxReso->currentText();
    QStringList strList = strTemp.split('x');
    QString strW = strList.first();
    QString strH = strList.last();
    tempReso.width = strW.toInt();
    tempReso.height = strH.toInt();

    emit  sigEveryResolution(tempReso);

    accept();
}

void ResolutionDialog::on_cancelBtn_clicked()
{
    reject();
}

上面只将这个出现上述问题的类的代码附上。因为其中涉及到项目中的一些需求实现,读者可以选择性读取,理解我说明的问题解决思路便好,代码可以参考。由于涉及到qss文件设置样式,那部分没有贴出来,读者可以注释掉背景透明和无边框的设置。

  • 10
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
Qt,您可以使用QMenu类创建下拉菜单或弹出式菜单。您可以添加自定义操作,例如QAction或QWidget,以在下拉菜单实现自定义操作。以下是一个示例: ```python from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QMenu, QAction class MainWindow(QMainWindow): def __init__(self): super().__init__() button = QPushButton("Click me", self) button.setFixedWidth(100) button.setFixedHeight(30) button.move(50, 50) button.clicked.connect(self.show_menu) self.show() def show_menu(self): menu = QMenu(self) action1 = QAction("Action 1", self) action2 = QAction("Action 2", self) menu.addAction(action1) menu.addAction(action2) widget_action = QAction("Custom Widget", self) widget = CustomWidget(self) widget_action.setDefaultWidget(widget) menu.addAction(widget_action) button = self.sender() menu.exec_(button.mapToGlobal(button.rect().bottomRight())) class CustomWidget(QPushButton): def __init__(self, parent=None): super().__init__("Custom Widget", parent) self.clicked.connect(self.custom_action) def custom_action(self): print("Custom action triggered") if __name__ == '__main__': app = QApplication([]) window = MainWindow() app.exec_() ``` 在这个示例,我们创建了一个QPushButton和一个QMenu,然后将两个QAction添加到QMenu。我们还使用一个自定义QWidget来添加一个自定义操作。当QPushButton被点击,我们调用show_menu函数来显示QMenu。在show_menu函数,我们添加了三个QAction到QMenu,其一个QAction绑定了我们的自定义QWidget。我们还将QMenu弹出位置设置在QPushButton的右下角。 当用户选择“Custom Widget”操作,我们将触发自定义QWidget自定义操作。在这个示例,我们只是简单地打印一条消息,但您可以执行任何自定义操作,例如显示一个对话框或调用一个函数。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肩上风骋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值