c++ - QDialog::move() 不考虑具有多个屏幕的 Ubuntu 上的任务栏

标签 c++ qt ubuntu qdialog

通常,使用 QDialog::move() 移动 QDialog 会将对话框定位在任务栏之外。
但是,在带有两个显示器的 Ubuntu 20.04 上,无框对话框并非如此:
bug_frameless
如果对话框不是无框的,则不会发生这种情况:
enter image description here
此行为已在 Ubuntu 20.04 上观察到。它也仅在某些配置下发生:

  • 主显示器需要在右侧,任务栏在左侧(两个显示器之间)
  • 左侧显示器的分辨率需要低于右侧显示器
  • 需要禁用小数缩放

  • 以下是屏幕截图中使用的最小可重现示例的代码:
    #ifndef BUGDIALOG_H
    #define BUGDIALOG_H
    
    #include <QDialog>
    
    namespace Ui {
    class BugDialog;
    }
    
    class BugDialog : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit BugDialog(QWidget *parent = nullptr);
        ~BugDialog();
    
    private slots:
        void on_moveButton_clicked();
    
    private:
        Ui::BugDialog *ui;
    };
    
    #endif // BUGDIALOG_H
    
    
    
    #include "bugdialog.h"
    #include "ui_bugdialog.h"
    
    BugDialog::BugDialog(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::BugDialog)
    {
        ui->setupUi(this);
        ui->xPosEdit->setText("3200");
        ui->yPosEdit->setText("1000");
    }
    
    BugDialog::~BugDialog()
    {
        delete ui;
    }
    
    void BugDialog::on_moveButton_clicked()
    {
        int x = ui->xPosEdit->text().toInt();
        int y = ui->yPosEdit->text().toInt();
        if (x > -1 && x > -1)
            move(x, y);
    }
    
    主窗口不太有趣,它只创建控制其 WindowFlags 属性的子窗口:
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include "bugdialog.h"
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private slots:
        void on_pushButton_clicked();
    
        void on_framelessBox_stateChanged(int arg1);
    
    private:
        void hideDialog();
    
        Ui::MainWindow *ui;
        BugDialog* dialog;
    };
    #endif // MAINWINDOW_H
    
    
    
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        dialog = new BugDialog(nullptr);
        dialog->hide();
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
        delete dialog;
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        if (dialog->isHidden())
        {
            dialog->show();
            ui->pushButton->setText("Hide dialog");
        }
        else
        {
            hideDialog();
        }
    }
    
    void MainWindow::on_framelessBox_stateChanged(int)
    {
        auto windowType = ui->framelessBox->isChecked() ? Qt::FramelessWindowHint : Qt::Dialog;
        dialog->setWindowFlags(windowType);
        hideDialog();
    }
    
    void MainWindow::hideDialog()
    {
        dialog->hide();
        ui->pushButton->setText("Show dialog");
    }
    
    这看起来像 Qt 中的一个错误。有谁知道这是否是预期的行为?或者如何解决这个问题?

    最佳答案

    对于这个问题,我没有找到合适的解决方案或令人满意的解决方法,但找到了一个部分解决方案,它是一半令人满意:

  • 在每个 move() 之前在对话框上,将其标志设置为 Qt::Window(无框架)并隐藏它。
  • 覆盖 moveEvent()处理程序,将窗口标志设置为 Qt::FramelessWindowHint 并显示它。

  • 以下是我在此示例中所做的两个更改:
    void BugDialog::on_moveButton_clicked()
    {
        int x = ui->xPosEdit->text().toInt();
        int y = ui->yPosEdit->text().toInt();
        if (x > -1 && x > -1)
        {
            hide();
            setWindowFlags(Qt::Window);
            move(x, y);
        }
    }
    
    void BugDialog::moveEvent(QMoveEvent *)
    {
        QTimer::singleShot(500, this, [this](){
            this->setWindowFlags(Qt::FramelessWindowHint);
            this->show();
        });
    }
    
    我也尝试改变对话画。这个想法是将窗口标志设置为“framefull”对话框,但将对话框绘制为好像它具有 FramelessWindowHint 标志。我发现这个想法没有可接受/负担得起的解决方案。

    关于c++ - QDialog::move() 不考虑具有多个屏幕的 Ubuntu 上的任务栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71085581/

    相关文章:

    ubuntu - 如何将 ABP 框架应用程序部署到 Ubuntu 服务器?

    linux - Makefile 将 .o 文件导出到与 .cpp 不同的路径

    c++ - 如何显示一个字符数字

    windows - Windows 上的 Qt 不显示动画 GIF

    qt - 嵌入在 Qt 应用程序中的 Emacs

    c++ - QPixmap 图像文件未出现在 QGraphicsScene 上

    node.js - 使 Node 服务器重启证明

    C++:abs有什么问题

    c++ - c++11 有类似 quint8 的东西吗?

    c++ - 返回值和局部变量的区别