提要
自定义的弹出窗口,窗口可以实现按下鼠标拖动,鼠标释放停止拖动,窗口中含有子控件,下拉列表,在点击下拉列表时窗口移动。
解决方法
因为点击下拉列表的时候,触发了窗口的移动事件,所以添加下拉列表的事件过滤。
下面附上实现代码:
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文件设置样式,那部分没有贴出来,读者可以注释掉背景透明和无边框的设置。