4

最近、Windows 7 マシンに Github for Windows をインストールしましたが、カスタム フレームが気に入りました。全体的なアプリケーション テーマに非常によく合い、独自のタイトルバー ボタンがあり、非常にうまくレイアウトされ、非常に流暢で、非常に自然に動作するように見えました。と。

少し掘り下げて、境界線を完全にクリアする 2 つのフラグを見つけました。少しカスタマイズした後、アプリの外観も直感的でありながら、古い Windows 境界線を持つすべてのアプリとは異なり、うまくカスタマイズされました。

問題は、他のウィンドウのように流暢で自然に反応するものではなく、グリッチがあり、マウスでウィンドウを簡単に移動できましたが、しばしばグリッチが発生し、望ましくない領域に移動できました。無効なボタンをクリックしてドラッグします。

showMaximize メソッドにリンクされた最大化ボタンは、ウィンドウ全体を拡大してデスクトップ全体を占めるようにしましたが、それでも移動できました (実際には完全に最大化されていませんでした)。

ウィンドウは、タスクバーをクリックして最小化するなどのシステム信号に応答しませんでした。

多くの修正を行った後、私は最終的にあきらめましたが、残念なことに、それがどのように見えるかを本当に理解し、Windows用のgithubが非常に直感的であるのと同じように、非常に直感的でした.

これを達成する方法はありますか、まだあきらめる準備ができていません。

生の Windows API アプリケーションを作成するときは、デフォルトで Windows 95 スタイルを継承するため、XP 組み込みスタイルにリンクする必要があることを知っています。Qt が接続されていない Windows 8 スタイルがあるかもしれません。 「まだ研究でそこまで行ってはいけません。

4

2 に答える 2

5

タスクバーをクリックしてウィンドウを最小化する

Qt::FramelessWindowHintの実装は限られているようです。このフラグが設定されている場合、Windows は、このウィンドウを最小化または最大化できないと見なします。純粋なwinapiで実装されたこのソリューションを試しました。タスクバーをクリックしてフレームレスウィンドウを最小化および復元すると、正常に機能します。Qt は、この機能をブロックするいくつかの悪いフラグを設定しているようです。それには正当な理由があるのか​​もしれませんが、私にはわかりません。

winapi と Qt を併用できますが面倒です。まず、ウィンドウ フラグを設定し、Qt を使用してウィンドウを表示した後、winapi コードを実行する必要があります。そうしないと、Qt はウィンドウ フラグを上書きします。

もう 1 つの問題は、winapi を使用して境界線を削除すると、ウィンドウのジオメトリが突然変更され、Qt がそれを認識しないことです。レンダリングとイベント マッピング (マウス クリック位置を含む) が無効になります。マッピングを更新する文書化された方法が見つかりませんでした。画面の向きが変更されたことを Qt に伝えることができ、ウィンドウ ジオメトリの再計算を強制できることがわかりました。しかし、これは汚いハックのように見えます。また、QWidget::windowHandleQt 4 には機能がなく、Qt 5 では「変更される可能性があります」。したがって、この方法は信頼できません。しかし、とにかく、それは今動作します。最上位のウィンドウ クラス コンストラクターに配置する必要がある完全なコード (Windows 8 でテスト済み) を次に示します。

#include "windows.h"
#include <QWindow>
//...
show();
HWND hwnd = reinterpret_cast<HWND>(effectiveWinId());
LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
lStyle &= ~(WS_CAPTION | WS_THICKFRAME | WS_MINIMIZE | WS_MAXIMIZE | WS_SYSMENU);
SetWindowLong(hwnd, GWL_STYLE, lStyle);
setWindowFlags(windowFlags() | Qt::FramelessWindowHint);
windowHandle()->reportContentOrientationChange(Qt::PrimaryOrientation);

この問題を解決する本当の方法は、Window Qt プラットフォーム プラグインを変更することです (Qt ソースの QWindowsWindow クラスを参照してください)。デフォルトの実装から継承し、それを変更してアプリで使用する方法があるかもしれません。また、Qt の開発者に、この動作が妥当なのか、それともバグなのかを尋ねることもできます。この問題はパッチで修正できると思います。

このコードを引き続き使用する予定で、他の OS もサポートする必要がある場合は、windows 固有の実装を でラップすることを忘れないでください#ifdef Q_OS_WIN

タイトル バーがクリックされ、ウィンドウが最大化されていない場合にのみ、ウィンドウのドラッグを有効にする

他の問題はより簡単に修正できます。マウス イベントを処理してウィンドウのドラッグを実装する場合は、ウィンドウの状態とイベントの位置を確認し、不要な場合は移動を無効にします。

void MainWindow::mousePressEvent(QMouseEvent *e) {
  if (!isMaximized() && 
      e->button() == Qt::LeftButton && 
      ui->title->geometry().contains(e->pos())) {
    window_drag_start_pos = e->pos();
  }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *e) {
  window_drag_start_pos = QPoint(0, 0);
}

void MainWindow::mouseMoveEvent(QMouseEvent *e) {
  if (!window_drag_start_pos.isNull()) {
    move(pos() + e->pos() - window_drag_start_pos);
  }
}

void MainWindow::on_minimize_clicked() {
  showMinimized();
}

void MainWindow::on_maximize_clicked() {
  if (isMaximized()) {
    showNormal();
  } else {
    showMaximized();
  }
}

これui->titleは、偽のタイトル バーを表示するために使用されるラベルQPoint window_drag_start_posで、クラス変数です。

于 2013-10-31T22:06:49.340 に答える