3

很久以前,我试图找到方法如何将 QDialog 窗口粘贴到我的小项目(如Skype窗口)的屏幕边框上,但我失败了。可能是我没有在正确的位置查看此代码,所以现在我正在这里寻找解决方案,在堆栈上!:)

那么,是否有人处理过某种此类代码、链接、示例?

在我看来,我们必须重新实现 QDialog moveEvent 函数,如下所示,但该代码不起作用:

void    CDialog::moveEvent(QMoveEvent * event) {

    QRect wndRect;
    int leftTaskbar = 0, rightTaskbar = 0, topTaskbar = 0, bottomTaskbar = 0;
//  int top = 0, left = 0, right = 0, bottom = 0;

    wndRect = this->frameGeometry();

    // Screen resolution
    int screenWidth =   QApplication::desktop()->width();
    int screenHeight =  QApplication::desktop()->height();

    int wndWidth = wndRect.right() - wndRect.left();
    int wndHeight = wndRect.bottom() - wndRect.top();

    int posX = event->pos().x();
    int posY = event->pos().y();

    // Snap to screen border
    // Left border
    if (posX >= -m_nXOffset + leftTaskbar &&
        posX <= leftTaskbar + m_nXOffset) {
        //left = leftTaskbar;
        this->move(leftTaskbar, posY);
        return;
    }

    // Top border
    if (posY >= -m_nYOffset &&
        posY <= topTaskbar + m_nYOffset) {
        //top = topTaskbar;
        this->move(posX, topTaskbar);
        return;
    }

    // Right border
    if (posX + wndWidth <= screenWidth - rightTaskbar + m_nXOffset &&
        posX + wndWidth >= screenWidth - rightTaskbar - m_nXOffset) {
        //right = screenWidth - rightTaskbar - wndWidth;
        this->move(screenWidth - rightTaskbar - wndWidth, posY);
        return;
    }

    // Bottom border
    if (posY + wndHeight <= screenHeight - bottomTaskbar + m_nYOffset &&
        posY + wndHeight >= screenHeight - bottomTaskbar - m_nYOffset) {
        //bottom = screenHeight - bottomTaskbar - wndHeight;
        this->move(posX, screenHeight - bottomTaskbar - wndHeight);
        return;
    }

    QDialog::moveEvent(event);
}

谢谢。

4

2 回答 2

1

正如您认为的那样,您可以在 moveEvent 函数中实现这一点。我想下面的代码可以解决问题,但是由于我在这里没有什么要测试的,所以我将编写一些伪代码:

首先获取可用的屏幕区域:

const QRect screen = QApplication::availableGeometry(this);
// This get the screen rect where you can drag a dialog

然后获取对话框相对于桌面的位置(如果您的对话框是其他小部件的子级,则需要将相对于桌面的小部件坐标转换为相对于桌面的坐标):

const QRect dialog = geometry();
// Do here transformation

现在测试对话框是否靠近屏幕边框

if( abs(dialog.left()-screen.left() < OFFSET )
    move(screen.left(), dialog.top();
else if( abs(dialog.top()-screen.top() < OFFSET )
    move(dialog.left(), screen.top() )
// etc. for the 2 other cases

让我知道它是否有效

于 2010-04-26T14:18:49.200 回答
1

在文档的pos属性描述QWidget,有以下关于在 move 事件处理方法中移动窗口的警告。

警告:调用move()setGeometry()内部moveEvent()可能导致无限递归。

也就是说,没有适当的方法将对话框窗口粘贴在屏幕边框内。

注意:您在 KDE 中观察到的行为来自窗口管理器。实际上,窗口管理器是安排应用程序窗口(如对话框)以在屏幕上显示它们的一种。KDE 窗口管理器有一个选项可以使所有应用程序窗口(称为客户端)都贴在边框上。

于 2010-05-11T16:28:37.547 回答