在我的开源项目中,我想添加一个扇区扫描功能。为此,我尝试创建一个类似于碎片整理软件产品的Widget。除了我不能使控件可滚动的问题之外,一切都在工作。我的代码总是会生成一个强制的大小,这样mdichild (父对象)就会调整大小,滚动就会在MdiArea中,而不是在窗口中。意味着它将把mdiHeader滚动出视图。

我希望控件本身变成滚动条来滚动,而mdichild窗口将保持它的大小。我的代码是:
MDICHild: mdichild_scan.cpp
#include <QtWidgets>
#include "mdichild_scan.h"
#include "FoxSDKBurningLib.h"
#include "mainwindow.h"
#include "settingspages.h"
#include "messanger.h"
MdiChildScan::MdiChildScan(QWidget* parent, const QString &device)
:strBurnDrive(device){
setAttribute(Qt::WA_DeleteOnClose);
mProjectType = RuleManager::TYPE_PROJECT_DEVICEINFO;
thisSuccessfullCreated = true;
QString wTitle = tr("Hex ");
wTitle += " (";
wTitle += strBurnDrive;
wTitle += ")";
setWindowTitle(wTitle);
QVBoxLayout * dlgSplitter = new QVBoxLayout(this);
QHBoxLayout * topNav = new QHBoxLayout(this);
QWidget * wdgSplitter = new QWidget(this);
QLabel *labelTopNav = new QLabel(this);
labelTopNav->setText(tr("This is a header"));
topNav->addWidget(labelTopNav);
topNav->setContentsMargins(1,8,1,0);
dlgSplitter->setContentsMargins(0,0,0,0);
dlgSplitter->setSpacing(0);
dlgSplitter->setMargin(0);
dlgSplitter->addLayout(topNav);
scanBoard = new QScanBoard(45, 65);
dlgSplitter->addWidget(scanBoard);
wdgSplitter->setLayout(dlgSplitter);
this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
this->setCentralWidget(wdgSplitter);
}mdichild_scan.h
#ifndef MDICHILD_SCAN_H
#define MDICHILD_SCAN_H
#include <QMainWindow>
#include <QtWidgets>
#include <QListView>
#include <QSplitter>
#include <QLabel>
#include "mdichild_base.h"
#include "FoxSDKBurningLib.h"
#include "vrulemanager.h"
#include "QScanBoard.h"
class MdiChildScan : public MdiChildBase
{
Q_OBJECT
public:
MdiChildScan(QWidget* parent, const QString &device);
RuleManager::ProjectType GetProjectType() {return mProjectType;}
bool thisSuccessfullCreated;
protected:
RuleManager::ProjectType mProjectType;
QString strBurnDrive;
private:
QScanBoard* scanBoard;
};
#endif控件本身: QScanBoard.cpp
#include "QScanBoard.h"
#include <QGridLayout>
#include <QScrollBar>
#include <QSet>
QScanBoard::QScanBoard(unsigned int numRows, unsigned int numCols, QWidget* parent)
: QAbstractScrollArea(parent)
, m_numRows(numRows)
, m_numCols(numCols)
{
setupLayout();
createTiles();
}
void QScanBoard::setupLayout()
{
this->setAttribute(Qt::WA_LayoutUsesWidgetRect);
this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
auto layout = new QGridLayout;
layout->setSpacing(0);
layout->setMargin(0);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSizeConstraint(QLayout::SetFixedSize);
setLayout(layout);
setFocusPolicy(Qt::StrongFocus);
verticalScrollBar()->setValue(0);
}
void QScanBoard::createTiles()
{
for (unsigned int r = 0; r < m_numRows; ++r)
{
m_tiles += QList<QScanTile*>{};
for (unsigned int c = 0; c < m_numCols; ++c)
{
// add a new tile to the row
m_tiles[r] += new QScanTile({ r, c }, this);
static_cast<QGridLayout*>(this->layout())->addWidget(m_tiles[r][c], r, c);
}
}
m_tiles[0][0]->setDown(true);
viewport() -> update();
}QScanBoard.h
#ifndef QSCANBOARD_H
#define QSCANBOARD_H
#pragma once
#include <QList>
#include <QFrame>
#include <QSet>
#include <QAbstractScrollArea>
#include "QScanTile.h"
class QScanBoard : public QAbstractScrollArea
{
Q_OBJECT
public:
QScanBoard(unsigned int numRows, unsigned int numCols, QWidget* parent = nullptr);
unsigned int numCols() const { return m_numCols; }
unsigned int numRows() const { return m_numRows; }
signals:
void initialized();
private:
void createTiles();
void setupLayout();
private:
unsigned int m_numRows;
unsigned int m_numCols;
QList<QList<QScanTile*>> m_tiles;
QSet<QScanTile*> m_sectors;
};
#endif // QSCANBOARD_H进度项: QScanTile.cpp
#include "QScanTile.h"
#include <thread>
#include <chrono>
#include <QDebug>
#include <QState>
#include <QFinalState>
#include <QMouseEvent>
#include <QSizePolicy>
const QString QScanTile::unrevealedStyleSheet =
"QScanTile"
"{"
" border: 1px solid darkgray;"
" background: qradialgradient(cx : 0.4, cy : -0.1, fx : 0.4, fy : -0.1, radius : 1.35, stop : 0 #fff, stop: 1 #bbb);"
" border - radius: 1px;"
"}";
const QString QScanTile::revealedStyleSheet =
"QScanTile"
"{"
" border: 1px solid lightgray;"
"}";
const QString QScanTile::revealedWithNumberStylesheet =
"QScanTile"
"{"
" color: %1;"
" font-weight: bold;"
" border: 1px solid lightgray;"
"}";
QIcon QScanTile::blankIcon()
{
static QIcon icon = QIcon();
return icon;
}
QScanTile::QScanTile(QScanTileLocation location, QWidget* parent /*= nullptr*/)
: m_adjacentFlaggedCount(0)
, m_location(location)
, QPushButton(parent)
{
this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
setCheckable(true);
this->setIcon(blankIcon());
this->setStyleSheet(unrevealedStyleSheet);
}
QScanTile::~QScanTile()
{
}
QScanTileLocation QScanTile::location() const
{
return m_location;
}
QSize QScanTile::sizeHint() const
{
return QSize(12, 12);
}QScanTile.h
#ifndef QSCANTILE_H
#define QSCANTILE_H
#pragma once
#include <QPushButton>
#include <QList>
#include <QStateMachine>
#include <QState>
#include <QFinalState>
#include <QSignalMapper>
struct QScanTileLocation
{
unsigned int row;
unsigned int column;
};
class QScanTile : public QPushButton
{
Q_OBJECT
public:
QScanTile(QScanTileLocation location, QWidget* parent = nullptr);
virtual ~QScanTile() override;
QScanTileLocation location() const;
virtual QSize sizeHint() const override;
static QIcon blankIcon();
private:
QScanTileLocation m_location;
static const QString unrevealedStyleSheet;
static const QString revealedStyleSheet;
static const QString revealedWithNumberStylesheet;
};
#endif // QSCANTILE_H我希望有人能帮助我为什么控件不会得到预期的滚动条。(见红色)

发布于 2019-11-21 17:33:45
我自己解决了。QAbstractArea是错误的方式。现在,它完美地工作了。
向MDI子级添加了一个ScrollArea,并将控件放在此
scanBoard = new QScanBoard(200, 83);
scrollArea->setWidget(scanBoard);控件从QAbstractScrollArea更改为QFrame。
https://stackoverflow.com/questions/58950349
复制相似问题