ShadeWidget を実現する為に必要な技術的な解説
前の説明で、 親ウインドウの説明が漏れていたので、 書いて置きます。
親ウインドウも背景は透明化
ShadeMain.cppShadeMain::ShadeMain(QWidget* parent)
: QDialog(parent)
{
// 枠なしウインドウ
Qt::WindowFlags flags = Qt::Dialog | Qt::WindowStaysOnTopHint;
flags |= Qt::FramelessWindowHint;
setWindowFlags(flags);
// 背景を透明に
setAttribute(Qt::WA_TranslucentBackground);
setMouseTracking(true);
モードをリサイズ許可の時は、 全ボタンを表示し、 リサイズ不可の時はボタンを見えなくするため、 背景は透明化します。
タイトルバーもいりません。
移動を親ウインドウで検知する
タイトルバーの代用品を用意しなければなりません。
マウスでつまんで移動を検知するために、 Movable
マウスイベントを検知する機能を追加した QPush
movablebutton.h#ifndef MOVABLEBUTTON_H
#define MOVABLEBUTTON_H
#include <QTextEdit>
#include <QPushButton>
#include <QObject>
class MovableButton : public QPushButton
{
Q_OBJECT
public:
MovableButton(QWidget * parent = 0 );
~MovableButton(){}
signals:
void mousePressed(QMouseEvent*);
void mouseReleased(QMouseEvent*);
void mouseMove(QMouseEvent*);
public slots:
protected:
void mousePressEvent(QMouseEvent * event);
void mouseReleaseEvent(QMouseEvent * event);
void mouseMoveEvent(QMouseEvent * event);
private:
};
#endif
movablebutton.cpp#include <QMouseEvent>
#include <QDesktopServices>
#include <QWidget>
#include <QApplication>
#include <QDebug>
#include "movablebutton.h"
MovableButton::MovableButton(QWidget * parent)
:QPushButton(parent)
{
setMouseTracking(true);
}
void MovableButton::mousePressEvent(QMouseEvent *ev)
{
if(ev->button() & Qt::LeftButton)
emit mousePressed(ev);
}
void MovableButton::mouseReleaseEvent(QMouseEvent *ev)
{
if(ev->button() & Qt::LeftButton)
emit mouseReleased(ev);
}
void MovableButton::mouseMoveEvent(QMouseEvent *ev)
{
emit mouseMove(ev);
}
これで準備できました。
親ウインドウの画面部品
shademain.cpp
#include "movablebutton.h"
: // 中略
// このソフトのバージョン表示ボタン
QHBoxLayout *layout = new QHBoxLayout;
layout->setContentsMargins(0,0,0,0);
m_btnAbout = new QToolButton(this);
m_btnAbout->setFixedWidth(20);
m_btnAbout->setFixedHeight(20);
m_btnAbout->setObjectName("btnAbout");
m_btnAbout->setCursor(QCursor());
m_btnAbout->setFocusPolicy(Qt::NoFocus);
m_btnAbout->setAutoRaise(true);
m_btnAbout->setIcon(QIcon(QPixmap(":/icons/shadewidget.png")));
m_btnAbout->setToolTip(QString::fromUtf8(" ShadeWidget について"));
connect(m_btnAbout, SIGNAL(clicked()), this, SLOT(about()));
layout->addWidget(m_btnAbout);
// Qt5.9.5の表示ボタン
m_btnAboutQt = new QToolButton(this);
m_btnAboutQt->setFixedWidth(20);
m_btnAboutQt->setFixedHeight(20);
m_btnAboutQt->setObjectName("btnAboutQt");
m_btnAboutQt->setCursor(QCursor());
m_btnAboutQt->setFocusPolicy(Qt::NoFocus);
m_btnAboutQt->setAutoRaise(true);
m_btnAboutQt->setIcon(QIcon(QPixmap(":/icons/qt-icon.png")));
m_btnAboutQt->setToolTip(QString::fromUtf8(" Qt ライブラリについて"));
connect(m_btnAboutQt, SIGNAL(clicked()), qApp, SLOT(aboutQt())); // qApp ここがみそ
layout->addWidget(m_btnAboutQt);
// これがタイトルバーの代わりのボタン
m_btnMovable = new MovableButton(this);
m_btnMovable->setFixedHeight(20);
connect(m_btnMovable, &MovableButton::mousePressed , this, &ShadeMain::onMousePressed);
connect(m_btnMovable, &MovableButton::mouseReleased, this, &ShadeMain::onMouseReleased);
connect(m_btnMovable, &MovableButton::mouseMove , this, &ShadeMain::onMouseMove);
m_btnMovable->setObjectName("btnMovable");
m_btnMovable->setMinimumWidth(m_wdgtW-240);
m_btnMovable->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
m_btnMovable->setToolTip(QString::fromUtf8("ここをドラグするとウインドウを動かせます"));
m_btnMovable->setCursor(QCursor());
m_btnMovable->setText(QString::fromUtf8("ShadeWiget"));
m_btnMovable->setFocusPolicy(Qt::NoFocus);
layout->addWidget(m_btnMovable);
// 透明度のスライダー
m_opacitySlider = new QSlider(Qt::Horizontal, this);
m_opacitySlider->setFixedHeight(20);
m_opacitySlider->setMinimumWidth(100);
m_opacitySlider->setToolTip(QString::fromUtf8("透明度¥nスライダーを動かして調整"));
m_opacitySlider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
m_opacitySlider->setMaximum(90);
m_opacitySlider->setMinimum(30);
m_opacitySlider->setFocusPolicy(Qt::NoFocus);
int opaval = (int)(cfg->m_opacity*100.0F);
m_opacitySlider->setValue(opaval);
SetOpacity(opaval);
// 直接は接続しない
connect(m_opacitySlider, &QSlider::valueChanged, this, &ShadeMain::SetOpacity);
layout->addWidget(m_opacitySlider);
// スペーサーが必要
QSpacerItem* spacer = new QSpacerItem(0, 0, QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
layout->addItem(spacer);
// モード変更ボタン
m_btnModeChange = new QToolButton(this);
m_btnModeChange->setFixedWidth(20);
m_btnModeChange->setFixedHeight(20);
m_btnModeChange->setObjectName("btnModeChange");
m_btnModeChange->setCursor(QCursor());
m_btnModeChange->setFocusPolicy(Qt::NoFocus);
m_btnModeChange->setAutoRaise(true);
// m_btnModeChange->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
connect(m_btnModeChange, &QAbstractButton::clicked, this, &ShadeMain::onModeChange);
layout->addWidget(m_btnModeChange);
// 終了ボタン
QToolButton* closebtn = new QToolButton(this);
closebtn->setObjectName("closebtn");
closebtn->setFixedWidth(20);
closebtn->setFixedHeight(20);
closebtn->setCursor(QCursor());
closebtn->setFocusPolicy(Qt::NoFocus);
closebtn->setAutoRaise(true);
closebtn->setIcon(QIcon(QPixmap(":/icons/monoclose.png")));
closebtn->setToolTip(QString::fromUtf8("閉じる"));
// closebtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
connect(closebtn, &QAbstractButton::clicked, this, &ShadeMain::close);
layout->addWidget(closebtn);
モード変更した時に、 set
この時の Expand 属性に工夫をしないと上手く動きませんでした。
次にマウスで移動した時の処理が必要です。
shademain.cpp
: // 中略
void ShadeMain::onMousePressed(QMouseEvent* event)
{
//save the press position (this is relative to the current widget)
m_pressPos = event->pos();
// qDebug() << __func__ << m_widgetname << m_pressPos;
isMoving = true;
}
// タイトルバー移動で ShadeWidgetも移動
void ShadeMain::onMouseMove(QMouseEvent* event)
{
if(isMoving){
QPoint diff = event->pos() - m_pressPos;
QPoint parentpos = this->pos();
QPoint newpos = parentpos + diff;
move(newpos);
m_wdgtX = newpos.x();
m_wdgtY = newpos.y();
// qDebug() << "newpos=" << newpos;
if(m_shadewdgt){
QPoint winpos = m_shadewdgt->pos() + diff;
// qDebug() << "winpos=" << winpos;
m_shadewdgt->move(winpos);
}
m_parentpos = newpos;
}
}
void ShadeMain::onMouseReleased(QMouseEvent*)
{
// qDebug() << __func__ << m_widgetname << window()->pos() << m_pressPos;
isMoving = false;
}
サンプルソースダウンロード
説明不足なので、 プログラムソースを残します。
最終更新日
2023-05-13