我有以下GUI有四个QGraphicView
个对象
每个视图下方都有四个工具按钮。为了最大化视图,我连接了工具按钮的信号以隐藏其他三个视图的插槽,并将大小策略设置为针对所有四个视图进行扩展。但它只适用于View1和View 4,其他视图显示以下结果:
我正在使用网格布局。 View2在左侧留下间隙,在右侧留下View3。当我隐藏剩余的时候,我没有理由看到为什么View 2和View 3会留下空隙。
答案 0 :(得分:1)
以下代码在Qt 4和Qt 5下适用于我。它利用State Machine Framework简化状态转换的管理。一个视图可见的状态是状态的子状态,没有显示视图。这消除了对显式信号槽连接的需要,并且不得不保留视图和按钮列表。
State
类仅用于调试目的,以显示状态转换。
唉,至少在Qt 4.8.5中存在一个错误(种族?),这使得属性分配在嵌套状态下并不总能正常工作。当使用具有重叠属性的嵌套状态时,有时所有视图和按钮都将被隐藏,尽管机器已进入正确状态。在下面的代码中有一个解决方法。
请注意,网格窗口小部件不能包含任何其他具有行/列跨度的窗口小部件!= 1.如果确实如此,隐藏窗口小部件周围的间距仍然可见。这就是为什么我使用了两个嵌套布局。
#include <QApplication>
#include <QWidget>
#include <QGridLayout>
#include <QPushButton>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QStateMachine>
#include <QPlainTextEdit>
#include <QPointer>
static const int N = 4;
static QPointer<QPlainTextEdit> logView;
class State : public QState
{
public:
explicit State(const QString& name, QState* parent = 0) : QState(parent) {
setObjectName(name);
}
protected:
virtual void onEntry(QEvent*) {
QString state = objectName();
QState* parent = this;
while ((parent = parent->parentState()) && !parent->objectName().isEmpty() )
{
state = parent->objectName() + "->" + state;
}
logView->appendHtml(QString("<font color=\"green\">Entering state: <b>%1</b></font>").arg(state));
}
virtual void onExit(QEvent*) {
QString state = objectName();
QState* parent = this;
while ((parent = parent->parentState()) && !parent->objectName().isEmpty() )
{
state = parent->objectName() + "->" + state;
}
logView->appendHtml(QString("<font color=\"red\">Exiting state: <b>%1</b></font>").arg(state));
}
};
class Widget : public QWidget {
public:
explicit Widget(bool qt4) {
QGridLayout *vert = new QGridLayout(this);
QGridLayout *layout = new QGridLayout;
layout->setContentsMargins(0, 0, 0, 0);
logView = new QPlainTextEdit;
logView->appendPlainText(QString("Qt %1").arg(QT_VERSION_STR));
vert->addLayout(layout, 0, 0, 1, 1);
vert->addWidget(logView, 1, 0, 1, 1);
QStateMachine * const machine = new QStateMachine(this);
machine->setObjectName("machine");
State * const all = new State("all", machine);
State * const none = new State("none", machine);
QList<QState*> ones;
for (int i = 0; i < N; ++ i) {
const QString label = QString("View %1").arg(i+1);
ones << new State(label, none);
}
for (int i = 0; i < N; ++ i) {
QState *one = ones[i];
QGraphicsView *view = new QGraphicsView;
QGraphicsScene *scene = new QGraphicsScene(view);
scene->addText(one->objectName());
view->setScene(scene);
layout->addWidget(view, 2*(i/2), i%2, 1, 1);
QPushButton *button = new QPushButton(one->objectName());
layout->addWidget(button, 2*(i/2)+1, i%2, 1, 1);
button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
all->assignProperty(view, "visible", true);
all->assignProperty(button, "visible", true);
if (qt4) {
// Workaround for a bug: properties in nested states are
// sometimes not set correctly, so we explicitly set all properties
// in one state.
foreach (QState* s, ones) {
s->assignProperty(view, "visible", s == one);
s->assignProperty(button, "visible", s == one);
}
} else {
none->assignProperty(view, "visible", false);
none->assignProperty(button, "visible", false);
one->assignProperty(view, "visible", true);
one->assignProperty(button, "visible", true);
}
all->addTransition(button, SIGNAL(clicked()), one);
one->addTransition(button, SIGNAL(clicked()), all);
if (!none->initialState()) none->setInitialState(one);
}
machine->setInitialState(all);
machine->start();
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w(QT_VERSION < QT_VERSION_CHECK(5,0,0));
w.show();
return a.exec();
}