2015-09-24 2 views
0

Эта программа должна создать коллекцию DraggableLabels в центральной области, перетащив ее с одной из предоставленных ярлыков с левой стороны. Как только они существуют, они должны иметь возможность перетаскивать и делать разные вещи при нажатии или длительном нажатии.Проблема с программным обеспечением QWidgets

enter image description here

Long щелкните работы, основанные на таймере от MouseDown к MouseUp, но не включена здесь для ясности.

  • MainWindow :: test() works: Он отображает значок, как и предполагалось, и я могу взаимодействовать с ним.
  • 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)); 
} 
+3

Можете ли вы уменьшить свой пример до пары дюжины линий? – AlexanderVX

+0

@AlexanderVX Учитывая мою неопытность с Qt (я привык к VisualStudio и не могу заставить Mono работать), я думаю, что это будет сложно. Я уже сильно сократил свой основной проект. В основном, возникает вопрос: «Почему этот раздел кода работает (MainWindow :: test), но когда я копирую/вставляю его где-то в другом месте, он не работает (MainWindow :: LabelMouseUp)?» Все остальное есть для контекста.Извините, что заставил вас пробираться сквозь него, но у меня закончились очевидные вещи, чтобы обрезать. Если кто-то еще захочет обмануть его еще немного, тогда идите прямо вперед. – AaronD

+0

Не могли бы вы пропустить код в отладчике, чтобы узнать, где именно он идет не так, и добавить эту информацию в свой вопрос? – Bowdzone

ответ

1

Глядя на ваш код я думаю, что вы должны добавить что-то вроде шоу()

От Qt Documenation :

Если вы добавите дочерний виджет к уже видимому виджету, вы должны явно показать ребенку, чтобы он был виден.

Причина, по которой она работает внутри вашей тестовой функции() probabyl, заключается в том, что этот код выполняется до того, как вы даже вызовеете app.exec().

newLabel->show()