Qt杂记(控件移动问题)

起因

因为被分派了一个bug, 需要解决弹出的对话框居中问题. 一开始我还觉得这个问题很简单, 直接用move就行了, 奈何怎么都不能居中. 经过一系列测试发现, 在获取父窗口的大小时, 会发生变动, 导致计算总会有偏差. 最后去翻了一下QDialog的源码, 找到了这么一个方法
Qt杂记(控件移动问题)_第1张图片
至此有了一个新的思路. 另外, 我也想起了侯捷大师的一句话: 源码之前, 了无秘密! 如果问题不能解决, 就多找找源码看看, 也许源码里面会有多种解决方法.

示例

通过这次修改bug, 我也在此总结一下目前我了解的一些移动控件位置的方法.

  1. moveCenter
    Qt杂记(控件移动问题)_第2张图片
    即, 移动控件的中心位置移动到指定点, 不会改变控件的大小.

  2. move
    Qt杂记(控件移动问题)_第3张图片
    将控件的x,和y点移动至指定点

  3. adjustPosition(这个方法, 是Qt内部的实现, 没有形成公共接口)

    	// 获取父窗口    
    	auto w = qobject_cast(this->parent());
    	QPoint p(0, 0);
    	int extraw = 0, extrah = 0, scrn = 0;
        if (w)
            w = w->window();
    	
    	// 获取实际桌面
        QRect desk;
        if (w) {
            scrn = QApplication::desktop()->screenNumber(w);
        } else if (QApplication::desktop()->isVirtualDesktop()) {
            scrn = QApplication::desktop()->screenNumber(QCursor::pos());
        } else {
            scrn = QApplication::desktop()->screenNumber(this);
        }
        desk = QApplication::desktop()->availableGeometry(scrn);
    
    	
        QWidgetList list = QApplication::topLevelWidgets();
        for (int i = 0; (extraw == 0 || extrah == 0) && i < list.size(); ++i) {
            QWidget * current = list.at(i);
            if (current->isVisible()) {
                int framew = current->geometry().x() - current->x();
                int frameh = current->geometry().y() - current->y();
    
                extraw = qMax(extraw, framew);
                extrah = qMax(extrah, frameh);
            }
        }
    
        // sanity check for decoration frames. With embedding, we
        // might get extraordinary values
        if (extraw == 0 || extrah == 0 || extraw >= 10 || extrah >= 40) {
            extrah = 40;
            extraw = 10;
        }
    
    
        if (w) {
            // Use mapToGlobal rather than geometry() in case w might
            // be embedded in another application
            QPoint pp = w->mapToGlobal(QPoint(0,0));
            p = QPoint(pp.x() + w->width()/2,
                pp.y() + w->height()/ 2);
        } else {
            // p = middle of the desktop
            p = QPoint(desk.x() + desk.width()/2, desk.y() + desk.height()/2);
        }
    
        // p = origin of this
        p = QPoint(p.x()-width()/2 - extraw,
            p.y()-height()/2 - extrah);
    
        if (p.x() + extraw + width() > desk.x() + desk.width())
            p.setX(desk.x() + desk.width() - width() - extraw);
        if (p.x() < desk.x())
            p.setX(desk.x());
    
        if (p.y() + extrah + height() > desk.y() + desk.height())
            p.setY(desk.y() + desk.height() - height() - extrah);
        if (p.y() < desk.y())
            p.setY(desk.y());
    
        move(p);
    

你可能感兴趣的:(Qt杂技,qt)