Эта программа должна создать коллекцию DraggableLabels в центральной области, перетащив ее с одной из предоставленных ярлыков с левой стороны. Как только они существуют, они должны иметь возможность перетаскивать и делать разные вещи при нажатии или длительном нажатии.Проблема с программным обеспечением QWidgets
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));
}
Можете ли вы уменьшить свой пример до пары дюжины линий? – AlexanderVX
@AlexanderVX Учитывая мою неопытность с Qt (я привык к VisualStudio и не могу заставить Mono работать), я думаю, что это будет сложно. Я уже сильно сократил свой основной проект. В основном, возникает вопрос: «Почему этот раздел кода работает (MainWindow :: test), но когда я копирую/вставляю его где-то в другом месте, он не работает (MainWindow :: LabelMouseUp)?» Все остальное есть для контекста.Извините, что заставил вас пробираться сквозь него, но у меня закончились очевидные вещи, чтобы обрезать. Если кто-то еще захочет обмануть его еще немного, тогда идите прямо вперед. – AaronD
Не могли бы вы пропустить код в отладчике, чтобы узнать, где именно он идет не так, и добавить эту информацию в свой вопрос? – Bowdzone