重写QDialog::showEvent

本文介绍了一个针对QDialog组件的问题解决方案,即如何确保弹窗能够相对于其父窗口正确显示而非固定在屏幕中央。通过重写showEvent函数并加入特定条件判断,可以实现弹窗位置的动态调整。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

重写该函数后,需要加上

    if (!event->spontaneous() && !testAttribute(Qt::WA_Moved)) {
        adjustPosition(parentWidget());//该函数就是调整对话框位置的函数
    }

否则QDialog弹出时将只会显示在屏幕中间,而不是跟随其父窗口

附QDialog::showEvent源码

void QDialog::showEvent(QShowEvent *event)
{
    if (!event->spontaneous() && !testAttribute(Qt::WA_Moved)) {
        Qt::WindowStates  state = windowState();
        adjustPosition(parentWidget());
        setAttribute(Qt::WA_Moved, false); // not really an explicit position
        if (state != windowState())
            setWindowState(state);
    }
}

关于event->spontaneous()可参考这里

Qt 的主事件循环(QCoreApplication::exec())从事件队列中获取本地窗口系统事件,将它们转化为 QEvents,然后将转换后的事件发送给 QObjects。

一般来说,事件来自底层窗口系统(spontaneous() 返回 true),但也可以使用 QCoreApplication::sendEvent() 和 QCoreApplication::postEvent()(spontaneous() 返回 false)来手动发送事件。

这是.h:#ifndef USERINFODIALOG_H #define USERINFODIALOG_H #include <QDialog> namespace Ui { class UserInfoDialog; } class UserInfoDialog : public QDialog { Q_OBJECT public: explicit UserInfoDialog(const QString &username, QWidget *parent = nullptr); ~UserInfoDialog(); private slots: void on_btnSave_clicked(); private: Ui::UserInfoDialog *ui; QString m_username; // 当前登录的用户名 }; #endif // USERINFODIALOG_H 这是.cpp:#include "userinfodialog.h" #include "ui_userinfodialog.h" #include <QSettings> #include <QMessageBox> UserInfoDialog::UserInfoDialog(const QString &username, QWidget *parent) : QDialog(parent), ui(new Ui::UserInfoDialog), m_username(username) { ui->setupUi(this); setWindowTitle("完善用户信息"); // 设置年龄范围 ui->spinAge->setRange(1, 150); // 设置性别选项 ui->comboGender->addItems(QStringList() << "男" << "女" << "其他"); } UserInfoDialog::~UserInfoDialog() { delete ui; } void UserInfoDialog::on_btnSave_clicked() { QString name = ui->txtName->text().trimmed(); int age = ui->spinAge->value(); QString gender = ui->comboGender->currentText(); // 验证输入 if (name.isEmpty()) { QMessageBox::warning(this, "错误", "姓名不能为空"); return; } // 保存到QSettings QSettings settings("user_data.ini", QSettings::IniFormat); settings.beginGroup("UserInfo/" + m_username); // 使用UserInfo分组下的用户名作为子分组 settings.setValue("name", name); settings.setValue("age", age); settings.setValue("gender", gender); settings.endGroup(); settings.sync(); // 同步到文件 QMessageBox::information(this, "成功", "用户信息已保存"); accept(); // 关闭对话框 } 这是报错的登录.cpp#include "qlineedit.h" #include <QMessageBox> #include <QSettings> // 简单存储用 QSettings #include "loginwindow.h" #include "ui_loginwindow.h" #include "adminloginwindow.h" #include "userinfodialog.h" LoginWindow::LoginWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::LoginWindow) { ui->setupUi(this); registerWindow = nullptr; this->setWindowTitle("登录窗口"); loadUserData(); // 初始化加载一次 } LoginWindow::~LoginWindow() { delete ui; if(registerWindow) delete registerWindow; } // 加载存储的账号密码(简单版:用 QSettings 存储) void LoginWindow::loadUserData() { QSettings settings("login_data.ini", QSettings::IniFormat); settings.beginGroup("Users"); userData.clear(); foreach (const QString &key, settings.allKeys()) { userData.insert(key, settings.value(key).toString()); } settings.endGroup(); qDebug() << "当前用户数据:" << userData; } void LoginWindow::showEvent(QShowEvent *event) { QMainWindow::showEvent(event); loadUserData(); } void LoginWindow::on_pushButton_Login_clicked() { QString inputUser = ui->lineEdit_Account->text().trimmed(); QString inputPass = ui->lineEdit_Password->text().trimmed(); if (inputUser.isEmpty() || inputPass.isEmpty()) { QMessageBox::warning(this, "错误", "请输入账号或密码"); return; } QSettings settings("login_data.ini", QSettings::IniFormat); settings.beginGroup("Users"); QStringList users = settings.childKeys(); // 获取所有用户 bool found = false; for (const QString &user : users) { if (user == inputUser && settings.value(user).toString() == inputPass) { found = true; break; } } settings.endGroup(); if (found) { QMessageBox::information(this, "成功", "登录成功!"); } else { QMessageBox::warning(this, "错误", "账号或密码错误"); ui->lineEdit_Password->clear(); } if (authenticate(...)) { this->hide(); // 隐藏登录窗口 UserInfoDialog *userInfoDialog = new UserInfoDialog(this); // 指定父对象,这样当父对象销毁时,对话框也会销毁 // 或者使用setAttribute(Qt::WA_DeleteOnClose); connect(userInfoDialog, &UserInfoDialog::finished, this, [this, userInfoDialog](int result) { // 当用户信息对话框关闭后,可以做一些处理,比如显示登录窗口或退出 if (result == QDialog::Accepted) { // 用户信息保存成功,可以退出程序或继续 this->close(); // 关闭登录窗口(程序退出) } else { // 用户取消了,重新显示登录窗口 this->show(); } userInfoDialog->deleteLater(); // 如果未设置WA_DeleteOnClose,则手动删除 }); userInfoDialog->show(); // 非模态显示 // 或者使用模态:userInfoDialog->exec(); 但使用exec()则不需要连接finished信号,因为exec()是阻塞的 } }
07-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值