This commit is contained in:
2026-05-15 00:06:14 +08:00
parent 83c2c26e89
commit b4c7697e8a
6 changed files with 174 additions and 45 deletions
+62 -5
View File
@@ -3,13 +3,18 @@
#include <QDialogButtonBox>
#include <QFrame>
#include <QLabel>
#include <QMessageBox>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QRadioButton>
#include <QStackedWidget>
#include <QVBoxLayout>
namespace {
const QString kDefaultFluxInpaintPrompt = QStringLiteral(
"这是一幅中国山水画的一部分,mask是被我去除的一个人物,现在需要在原来的位置填充与周围画布连贯的背景");
QPushButton* makeAlgoButton(const QString& title, QWidget* parent) {
auto* btn = new QPushButton(parent);
btn->setCheckable(false);
@@ -41,6 +46,13 @@ BlackholeResolveDialog::BlackholeResolveDialog(const QString& blackholeName, QWi
m_pages->setCurrentWidget(m_pageSelect);
}
QString BlackholeResolveDialog::inpaintModelKey() const {
if (m_radioFlux && m_radioFlux->isChecked()) {
return QStringLiteral("flux_fill");
}
return QStringLiteral("lama");
}
QString BlackholeResolveDialog::promptText() const {
return m_promptEdit ? m_promptEdit->toPlainText().trimmed() : QString();
}
@@ -104,7 +116,7 @@ void BlackholeResolveDialog::buildDetailPage() {
auto* pLay = new QVBoxLayout(panel);
pLay->setSpacing(8);
auto* tip = new QLabel(QStringLiteral("应用后在画布拖取样"), panel);
auto* tip = new QLabel(QStringLiteral("在画布拖取样。"), panel);
tip->setStyleSheet("color: palette(mid);");
pLay->addWidget(tip);
cLay->addWidget(panel);
@@ -116,13 +128,13 @@ void BlackholeResolveDialog::buildDetailPage() {
{
auto* oLay = new QVBoxLayout(m_originalDetail);
oLay->setSpacing(8);
auto* desc = new QLabel(QStringLiteral("仅隐藏黑洞,不改动背景文件"), m_originalDetail);
auto* desc = new QLabel(QStringLiteral("不修改背景原图"), m_originalDetail);
desc->setWordWrap(true);
oLay->addWidget(desc);
oLay->addStretch(1);
}
// 详情页 C:模型补全(提示词)
// 详情页 C:模型补全
m_modelDetail = new QWidget(m_algoDetails);
{
auto* mLay = new QVBoxLayout(m_modelDetail);
@@ -133,11 +145,49 @@ void BlackholeResolveDialog::buildDetailPage() {
auto* pLay = new QVBoxLayout(panel);
pLay->setSpacing(8);
m_radioLama = new QRadioButton(QStringLiteral("LaMa"), panel);
m_radioFlux = new QRadioButton(QStringLiteral("FLUX Fill"), panel);
m_radioLama->setChecked(true);
pLay->addWidget(m_radioLama);
pLay->addWidget(m_radioFlux);
m_promptLabel = new QLabel(QStringLiteral("提示词"), panel);
pLay->addWidget(m_promptLabel);
m_promptEdit = new QPlainTextEdit(panel);
m_promptEdit->setPlaceholderText(QStringLiteral("可选"));
m_promptEdit->setMinimumHeight(72);
m_promptLabel->setVisible(false);
m_promptEdit->setVisible(false);
pLay->addWidget(m_promptEdit);
auto syncPromptUi = [this]() {
if (!m_promptEdit || !m_promptLabel) {
return;
}
const bool flux = m_radioFlux && m_radioFlux->isChecked();
m_promptLabel->setVisible(flux);
m_promptEdit->setVisible(flux);
if (flux) {
m_promptEdit->setEnabled(true);
if (m_promptEdit->toPlainText().trimmed().isEmpty()) {
m_promptEdit->setPlainText(kDefaultFluxInpaintPrompt);
}
} else {
m_promptEdit->setEnabled(false);
}
};
connect(m_radioLama, &QRadioButton::toggled, this, [syncPromptUi](bool on) {
if (on) {
syncPromptUi();
}
});
connect(m_radioFlux, &QRadioButton::toggled, this, [syncPromptUi](bool on) {
if (on) {
syncPromptUi();
}
});
syncPromptUi();
mLay->addWidget(panel);
mLay->addStretch(1);
}
@@ -154,7 +204,14 @@ void BlackholeResolveDialog::buildDetailPage() {
connect(btnBack, &QPushButton::clicked, this, [this]() {
m_pages->setCurrentWidget(m_pageSelect);
});
connect(btnApply, &QPushButton::clicked, this, &QDialog::accept);
connect(btnApply, &QPushButton::clicked, this, [this]() {
if (m_selectedAlgorithm == Algorithm::ModelInpaint && m_radioFlux && m_radioFlux->isChecked() &&
promptText().isEmpty()) {
QMessageBox::warning(this, QStringLiteral("模型补全"), QStringLiteral("请填写提示词。"));
return;
}
accept();
});
connect(btnCancel, &QPushButton::clicked, this, &QDialog::reject);
layout->addWidget(btns);
+8 -1
View File
@@ -3,6 +3,8 @@
#include <QDialog>
class QLabel;
class QPlainTextEdit;
class QRadioButton;
class QStackedWidget;
class BlackholeResolveDialog final : public QDialog {
@@ -17,6 +19,8 @@ public:
explicit BlackholeResolveDialog(const QString& blackholeName, QWidget* parent = nullptr);
Algorithm selectedAlgorithm() const { return m_selectedAlgorithm; }
QString inpaintModelKey() const;
QString promptText() const;
private:
@@ -41,6 +45,9 @@ private:
QWidget* m_originalDetail = nullptr;
QWidget* m_modelDetail = nullptr;
class QPlainTextEdit* m_promptEdit = nullptr;
QRadioButton* m_radioLama = nullptr;
QRadioButton* m_radioFlux = nullptr;
QLabel* m_promptLabel = nullptr;
QPlainTextEdit* m_promptEdit = nullptr;
};
+55 -28
View File
@@ -1,11 +1,13 @@
#include "dialogs/InpaintPreviewDialog.h"
#include <QDialogButtonBox>
#include <QHBoxLayout>
#include <QEvent>
#include <QLabel>
#include <QPixmap>
#include <QScrollArea>
#include <QResizeEvent>
#include <QShowEvent>
#include <QSplitter>
#include <QTimer>
#include <QVBoxLayout>
static QLabel* makeImageLabel(QWidget* parent) {
@@ -14,17 +16,10 @@ static QLabel* makeImageLabel(QWidget* parent) {
lab->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
lab->setScaledContents(false);
lab->setAlignment(Qt::AlignCenter);
lab->setMinimumSize(1, 1);
return lab;
}
static QScrollArea* wrapScroll(QWidget* child, QWidget* parent) {
auto* sc = new QScrollArea(parent);
sc->setWidget(child);
sc->setWidgetResizable(false);
sc->setBackgroundRole(QPalette::Dark);
return sc;
}
InpaintPreviewDialog::InpaintPreviewDialog(const QString& title, QWidget* parent)
: QDialog(parent) {
setModal(true);
@@ -37,14 +32,12 @@ InpaintPreviewDialog::InpaintPreviewDialog(const QString& title, QWidget* parent
m_beforeLabel = makeImageLabel(this);
m_afterLabel = makeImageLabel(this);
m_beforeScroll = wrapScroll(m_beforeLabel, this);
m_afterScroll = wrapScroll(m_afterLabel, this);
m_beforeScroll->setMinimumHeight(200);
m_afterScroll->setMinimumHeight(200);
m_beforeLabel->installEventFilter(this);
m_afterLabel->installEventFilter(this);
auto* splitter = new QSplitter(Qt::Horizontal, this);
splitter->addWidget(m_beforeScroll);
splitter->addWidget(m_afterScroll);
splitter->addWidget(m_beforeLabel);
splitter->addWidget(m_afterLabel);
splitter->setStretchFactor(0, 1);
splitter->setStretchFactor(1, 1);
root->addWidget(splitter, 1);
@@ -58,17 +51,51 @@ InpaintPreviewDialog::InpaintPreviewDialog(const QString& title, QWidget* parent
}
void InpaintPreviewDialog::setImages(const QImage& before, const QImage& after) {
if (m_beforeLabel) {
const QPixmap pb = QPixmap::fromImage(before);
m_beforeLabel->setPixmap(pb);
m_beforeLabel->setMinimumSize(pb.size());
m_beforeLabel->resize(pb.size());
}
if (m_afterLabel) {
const QPixmap pa = QPixmap::fromImage(after);
m_afterLabel->setPixmap(pa);
m_afterLabel->setMinimumSize(pa.size());
m_afterLabel->resize(pa.size());
}
m_beforeImg = before;
m_afterImg = after;
updateScaledPreviews();
QTimer::singleShot(0, this, [this]() { updateScaledPreviews(); });
}
void InpaintPreviewDialog::resizeEvent(QResizeEvent* e) {
QDialog::resizeEvent(e);
updateScaledPreviews();
}
void InpaintPreviewDialog::showEvent(QShowEvent* e) {
QDialog::showEvent(e);
updateScaledPreviews();
}
bool InpaintPreviewDialog::eventFilter(QObject* watched, QEvent* event) {
if (!m_inUpdateScaledPreviews && event->type() == QEvent::Resize) {
if (watched == m_beforeLabel || watched == m_afterLabel) {
updateScaledPreviews();
}
}
return QDialog::eventFilter(watched, event);
}
void InpaintPreviewDialog::updateScaledPreviews() {
if (m_inUpdateScaledPreviews) {
return;
}
m_inUpdateScaledPreviews = true;
auto fit = [](QLabel* lab, const QImage& src) {
if (!lab || src.isNull()) {
if (lab) {
lab->clear();
}
return;
}
const QSize cap = lab->size();
if (cap.width() < 2 || cap.height() < 2) {
return;
}
const QImage scaled = src.scaled(cap, Qt::KeepAspectRatio, Qt::SmoothTransformation);
lab->setPixmap(QPixmap::fromImage(scaled));
};
fit(m_beforeLabel, m_beforeImg);
fit(m_afterLabel, m_afterImg);
m_inUpdateScaledPreviews = false;
}
+13 -4
View File
@@ -3,8 +3,10 @@
#include <QDialog>
#include <QImage>
class QEvent;
class QLabel;
class QScrollArea;
class QShowEvent;
class QResizeEvent;
class InpaintPreviewDialog final : public QDialog {
Q_OBJECT
@@ -13,10 +15,17 @@ public:
void setImages(const QImage& before, const QImage& after);
protected:
void resizeEvent(QResizeEvent* e) override;
void showEvent(QShowEvent* e) override;
bool eventFilter(QObject* watched, QEvent* event) override;
private:
void updateScaledPreviews();
QLabel* m_beforeLabel = nullptr;
QLabel* m_afterLabel = nullptr;
QScrollArea* m_beforeScroll = nullptr;
QScrollArea* m_afterScroll = nullptr;
QImage m_beforeImg;
QImage m_afterImg;
bool m_inUpdateScaledPreviews = false;
};