3

ずっと前に、 Skypeウィンドウのような小さなプロジェクトで QDialog ウィンドウを画面の境界線に固定する方法を見つけようとしましたが、失敗しました。このコードを適切な場所で探していなかった可能性があるため、ここでスタック上のソリューションを探しています! :)

では、そのようなコード、リンク、サンプルのようなものを扱っている人はいますか?

私の意見では、以下のように 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

ドキュメントのposプロパティの説明QWidgetは、moveイベント処理メソッド内でのウィンドウの移動に関する次の警告があります。

警告:呼び出しmove()またはsetGeometry()内部でmoveEvent()は、無限の再帰が発生する可能性があります。

とはいえ、画面の境界線の内側にダイアログウィンドウを貼り付ける適切な方法はありません。

注:KDEで観察された動作は、ウィンドウマネージャーからのものです。実際には、ウィンドウマネージャーは、アプリケーションウィンドウ(ダイアログボックスなど)を画面に表示するように配置するものです。KDEウィンドウマネージャには、すべてのアプリケーションウィンドウ(クライアントと呼ばれる)を境界線に固定するオプションがあります。

于 2010-05-11T16:28:37.547 に答える
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 に答える