无法以编程方式创建QWidgets

时间:2015-09-24 04:08:57

标签: c++ qt qt5

该程序应该通过从左侧提供的标签之一拖动来在中心区域创建DraggableLabels的集合。一旦它们存在,它们应该能够在单击或长按时拖动并执行不同的操作。

enter image description here

长按点击工作,基于从MouseDown到MouseUp的计时器,但为清晰起见,此处未包含此内容。

  • MainWindow :: test()有效:它显示了它应该的图标,我可以与之交互。
  • MainWindow :: LabelMouseUp(..)不起作用:它没有显示任何内容,我似乎无法用鼠标找到它。 allScenes列表确实在增长,所以我知道它已经开始使用该代码。

我做错了什么想法?特别是为什么test()函数有效,但当我将其代码复制/粘贴到我想要的LabelMouseUp()中时,它不会?

我也愿意接受更好的方式。

Lights.pro:

#-------------------------------------------------
#
# Project created by QtCreator 2015-09-19T12:47:09
#
#-------------------------------------------------

QT      += core gui
CONFIG  += C++11

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Lights
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp \
    draggablelabel.cpp

HEADERS  += mainwindow.h \
    draggablelabel.h

main.cpp中:

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    new MainWindow();
    return app.exec();
}

draggablelabel.h:

#ifndef DRAGGABLELABEL_H
#define DRAGGABLELABEL_H

#include <QLabel>
#include <QMouseEvent>
#include <QEvent>

class DraggableLabel : public QLabel
{
    Q_OBJECT
public:
    explicit DraggableLabel(QWidget *parent = 0);

    void mousePressEvent(QMouseEvent* ev);
    void mouseReleaseEvent(QMouseEvent* ev);
    void mouseMoveEvent(QMouseEvent* ev);

signals:
    void MouseDown(DraggableLabel* sender, int x, int y);
    void MouseUp(DraggableLabel* sender, int x, int y);
    void MouseMove(DraggableLabel* sender, int x, int y);

public slots:

};

#endif // DRAGGABLELABEL_H

draggablelabel.cpp:

#include "draggablelabel.h"

DraggableLabel::DraggableLabel(QWidget *parent) :
    QLabel(parent)
{
}

void DraggableLabel::mousePressEvent(QMouseEvent *ev)
{
    emit MouseDown(this, ev->x(), ev->y());
    ev->accept();
}

void DraggableLabel::mouseReleaseEvent(QMouseEvent *ev)
{
    emit MouseUp(this, ev->x(), ev->y());
    ev->accept();
}

void DraggableLabel::mouseMoveEvent(QMouseEvent *ev)
{
    emit MouseMove(this, ev->x(), ev->y());
    ev->accept();
}

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtWidgets>
#include "draggablelabel.h"

class ResizeFilter : public QObject
{
    Q_OBJECT

public:
    ResizeFilter();

protected:
    bool eventFilter(QObject* obj, QEvent* event);

signals:
    void ResizeEvent(QSize size);
};



class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    ResizeFilter* filter;

    QPixmap* newPixmap;
    QPixmap* filePixmap;

    QWidget* pageScenes;
    QWidget* panelScenes;
    QWidget* panelSceneButtons;
    DraggableLabel* labelSceneNew;
    DraggableLabel* labelSceneFile;

    int panelwidth;

    QList<DraggableLabel*>* allScenes;

    bool mouseIsDown;

    QPlainTextEdit* debugLabel;

    QString IdentifyFunctionLabel(DraggableLabel* label);

    void test();

private slots:
    void FinishInit(QSize size);

    void LabelMouseDown(DraggableLabel* sender, int x, int y);
    void LabelMouseUp(DraggableLabel* sender, int x, int y);
    void LabelMouseMove(DraggableLabel* sender, int x, int y);
};

#endif // MAINWINDOW_H

mainwindow.cpp:

#include "mainwindow.h"

ResizeFilter::ResizeFilter()
    : QObject()
{

}

bool ResizeFilter::eventFilter(QObject *obj, QEvent *event)
{
    if(event->type() == QEvent::Resize)
    {
        QResizeEvent* resizeEv = static_cast<QResizeEvent*>(event);
        emit ResizeEvent(resizeEv->size());
    }
    return QObject::eventFilter(obj, event);
}



MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    filter = new ResizeFilter();
    installEventFilter(filter);
    showMaximized();    //do this before connecting so we miss the first resize event (wrong size) and catch the second (right size)
    connect(filter, SIGNAL(ResizeEvent(QSize)),
            this, SLOT(FinishInit(QSize)));
}

void MainWindow::FinishInit(QSize size)
{
    disconnect(filter, SIGNAL(ResizeEvent(QSize)),
               this, SLOT(FinishInit(QSize)));
    delete filter;

    allScenes = new QList<DraggableLabel*>();

    mouseIsDown = false;

    QString filepath = QCoreApplication::applicationDirPath();

    newPixmap = new QPixmap(filepath + "/Icons/New.png");
    filePixmap = new QPixmap(filepath + "/Icons/File.png");

    QWidget* centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);

    pageScenes = new QWidget(centralWidget);
    panelScenes = new QWidget(pageScenes);
    panelScenes->setStyleSheet("background-color: darkgray");
    panelSceneButtons = new QWidget(pageScenes);
    panelSceneButtons->setStyleSheet("background-color: lightgray");
    labelSceneNew = new DraggableLabel(panelSceneButtons);
    labelSceneNew->setStyleSheet("background-color: darkgray");
    labelSceneNew->setPixmap(*newPixmap);
    labelSceneNew->setAlignment(Qt::AlignCenter);
    labelSceneFile = new DraggableLabel(panelSceneButtons);
    labelSceneFile->setStyleSheet("background-color: darkgray");
    labelSceneFile->setPixmap(*filePixmap);
    labelSceneFile->setAlignment(Qt::AlignCenter);

    debugLabel = new QPlainTextEdit(centralWidget);
    debugLabel->setReadOnly(true);
    debugLabel->setStyleSheet("background-color: white");
    debugLabel->setFont(QFont("Courier New", 7));

    int fullwidth = size.width();
    int fullheight = size.height();
        panelwidth = fullwidth/10;
    int buttonborder = 1;
    int buttonsize = panelwidth-(2*buttonborder);

    panelScenes->setGeometry(panelwidth, 0, fullwidth-(2*panelwidth), fullheight);                      //center area for user's canvas
    panelSceneButtons->setGeometry(0, 0, panelwidth, fullheight);                                       //button area on the left side
    labelSceneNew->setGeometry(buttonborder, buttonborder, buttonsize, buttonsize);                     //buttons on the left side
    labelSceneFile->setGeometry(buttonborder, buttonsize+(3*buttonborder), buttonsize, buttonsize);     //buttons on the left side (count borders from top, including one of its own)

    debugLabel->setGeometry(fullwidth-(panelwidth), 0, panelwidth, fullheight);

    connect(labelSceneNew, SIGNAL(MouseDown(DraggableLabel*,int,int)),
            this, SLOT(LabelMouseDown(DraggableLabel*,int,int)));
    connect(labelSceneNew, SIGNAL(MouseUp(DraggableLabel*,int,int)),
            this, SLOT(LabelMouseUp(DraggableLabel*,int,int)));
    connect(labelSceneNew, SIGNAL(MouseMove(DraggableLabel*,int,int)),
            this, SLOT(LabelMouseMove(DraggableLabel*,int,int)));

    connect(labelSceneFile, SIGNAL(MouseDown(DraggableLabel*,int,int)),
            this, SLOT(LabelMouseDown(DraggableLabel*,int,int)));
    connect(labelSceneFile, SIGNAL(MouseUp(DraggableLabel*,int,int)),
            this, SLOT(LabelMouseUp(DraggableLabel*,int,int)));
    connect(labelSceneFile, SIGNAL(MouseMove(DraggableLabel*,int,int)),
            this, SLOT(LabelMouseMove(DraggableLabel*,int,int)));

    test();
}

MainWindow::~MainWindow()
{

}

void MainWindow::test()
{
    DraggableLabel* newlabel = new DraggableLabel(panelScenes);
    newlabel->setStyleSheet("background-color: darkgray");
    newlabel->setPixmap(*newPixmap);
    newlabel->setAlignment(Qt::AlignCenter);
    newlabel->setGeometry(200, 200, 100, 100);  //icons are 96 x 96
    connect(newlabel, SIGNAL(MouseDown(DraggableLabel*,int,int)),
            this, SLOT(LabelMouseDown(DraggableLabel*,int,int)));
    connect(newlabel, SIGNAL(MouseUp(DraggableLabel*,int,int)),
            this, SLOT(LabelMouseUp(DraggableLabel*,int,int)));
    connect(newlabel, SIGNAL(MouseMove(DraggableLabel*,int,int)),
            this, SLOT(LabelMouseMove(DraggableLabel*,int,int)));
    *allScenes << newlabel;
}

QString MainWindow::IdentifyFunctionLabel(DraggableLabel* label)
{
    if(label == labelSceneNew)      return "  SceneNew ";
    if(label == labelSceneFile)     return "  SceneFile";
                                    return "??unknown??";
}

void MainWindow::LabelMouseDown(DraggableLabel* sender, int x, int y)
{
    debugLabel->appendPlainText(QString("%1: Down:%2,%3").arg(IdentifyFunctionLabel(sender)).arg(x).arg(y));

    mouseIsDown = true;
}

void MainWindow::LabelMouseUp(DraggableLabel* sender, int x, int y)
{
    debugLabel->appendPlainText(QString("%1:   Up:%2,%3").arg(IdentifyFunctionLabel(sender)).arg(x).arg(y));

    if(!mouseIsDown)
    {
        return;
    }

    if(x > panelwidth)
    {
        QWidget* panel = nullptr;
        QPixmap* pixmap = nullptr;
        if(sender == labelSceneNew)
        {
            pixmap = newPixmap;
            panel = panelScenes;
        }
        if(sender == labelSceneFile)
        {
            pixmap = filePixmap;
            panel = panelScenes;
        }
        if(panel != nullptr)
        {
            DraggableLabel* newlabel = new DraggableLabel(panel);
            newlabel->setStyleSheet("background-color: darkgray");
            newlabel->setPixmap(*pixmap);
            newlabel->setAlignment(Qt::AlignCenter);
            newlabel->setGeometry(x, y, 100, 100);  //icons are 96 x 96
            connect(newlabel, SIGNAL(MouseDown(DraggableLabel*,int,int)),
                    this, SLOT(LabelMouseDown(DraggableLabel*,int,int)));
            connect(newlabel, SIGNAL(MouseUp(DraggableLabel*,int,int)),
                    this, SLOT(LabelMouseUp(DraggableLabel*,int,int)));
            connect(newlabel, SIGNAL(MouseMove(DraggableLabel*,int,int)),
                    this, SLOT(LabelMouseMove(DraggableLabel*,int,int)));
            *allScenes << newlabel;
        }
    }

    mouseIsDown = false;
}

void MainWindow::LabelMouseMove(DraggableLabel* sender, int x, int y)
{
    debugLabel->appendPlainText(QString("%1: Move:%2,%3").arg(IdentifyFunctionLabel(sender)).arg(x).arg(y));
}

1 个答案:

答案 0 :(得分:1)

看看你的代码,我猜你应该添加像show()

这样的东西

来自Qt Documenation

  

如果您将子窗口小部件添加到已经可见的窗口小部件,则必须   明确地显示孩子使其可见。

它在test()函数probabyl中工作的原因是这个代码在你调用app.exec()之前执行。

newLabel->show()