新手求教QT5利用QLabel设计一个添加波形的界面问题

dqy0582 2015-09-30 02:13:47
我利用QLabel重写重绘函数实现了一些波形,重写鼠标事件实现了QLabel的移动,但是还是有一些问题,我想让这些波形只能摆在x轴上,只能在x轴上用鼠标拖动而不能随意拖动,还有就是我点击按钮添加波形的时候之前添加移动过的波形又还原最初的位置了,我想在添加波形的时候之前移动过的波形保持原来的位置,求高手帮忙修改一下我的程序,或者能给一些指导建议也行,谢谢了!
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);

///布局按钮界面
buttonwidget_=new ButtonWidget;
w1_=new QPushButton;
w1_->setText(tr("wave1"));
w2_=new QPushButton;
w2_->setText(tr("wave2"));
buttonlayout_=new QVBoxLayout(buttonwidget_);
buttonlayout_->setMargin(10);
buttonlayout_->setAlignment(Qt::AlignCenter);
buttonlayout_->addWidget(w1_);
buttonlayout_->addWidget(w2_);

///连接按钮点击和槽函数
connect(w1_,SIGNAL(clicked()),this,SLOT(create_wave1()));
connect(w2_,SIGNAL(clicked()),this,SLOT(create_wave2()));

///整体布局
drawwidget_=new DrawWidget;
QWidget *widget=new QWidget;
mainlayout_=new QGridLayout(widget);
mainlayout_->addWidget(buttonwidget_,0,0);
mainlayout_->addWidget(drawwidget_,0,1);
setCentralWidget(widget);
}

MainWindow::~MainWindow()
{
delete ui;
}

void MainWindow::create_wave1(){
wave1_=new Wave1;
drawwidget_->wavelayout_->addWidget(wave1_,0,0);

}

void MainWindow::create_wave2(){
wave2_=new Wave2;
drawwidget_->wavelayout_->addWidget(wave2_,1,0);
}

#include "drawwidget.h"
#include <QPainter>

DrawWidget::DrawWidget(QWidget *parent) : QWidget(parent)
{
setAutoFillBackground(true);
setPalette(QPalette(Qt::white));
setMinimumSize(600,400);
wavelayout_=new QGridLayout(this);
}

void DrawWidget::paintEvent(QPaintEvent *event){
///绘制坐标轴
QPainter painter(this);
painter.setPen(QPen(Qt::black,2));
painter.drawLine(50,350,550,350);
painter.drawLine(548,348,550,350);
painter.drawLine(548,352,550,350);
painter.drawText(560,352,tr("x"));
}

#include "wave1.h"
#include <QPainter>
#include <QMouseEvent>

/*使用贝赛尔曲线画法的波形1,继承自QLabel,用到函数cubicTo()*/
Wave1::Wave1()
{
}

void Wave1::paintEvent(QPaintEvent *event){
QPainter painter(this);
QPainterPath path;
path. moveTo(0,100);
path. cubicTo(30,0,70,0,100,100);
painter.setPen(QPen(Qt::blue,2));
painter. setBrush( QBrush ( Qt :: green, Qt :: DiagCrossPattern));
painter.drawPath(path);
}

void Wave1::mousePressEvent(QMouseEvent *event){
if(event->button()==Qt::LeftButton)
{
dragPosition_=event->globalPos()-frameGeometry().topLeft();
event->accept();
}
}

void Wave1::mouseMoveEvent(QMouseEvent *event){
if(event->buttons()&Qt::LeftButton)
{
move(event->globalPos()-dragPosition_);
event->accept();
}

#include "wave2.h"
#include <QPainter>
#include <QMouseEvent>

/*使用线段画法的波形2,继承自QLabel,用到函数lineTo()*/
Wave2::Wave2()
{
}

void Wave2::paintEvent(QPaintEvent *event){
QPainter painter(this);
QPainterPath path;
path. moveTo(0,100);
path.lineTo(30,50);
path.lineTo(50,70);
path.lineTo(70,30);
path.lineTo(100,100);
painter.setPen(QPen(Qt::red,2));
painter. setBrush( QBrush ( Qt :: green, Qt :: DiagCrossPattern));
painter.drawPath(path);
}

void Wave2::mousePressEvent(QMouseEvent *event){
if(event->button()==Qt::LeftButton)
{
dragPosition_=event->globalPos()-frameGeometry().topLeft();
event->accept();
}
}

void Wave2::mouseMoveEvent(QMouseEvent *event){
if(event->buttons()&Qt::LeftButton)
{
move(event->globalPos()-dragPosition_);
event->accept();
}
}

实际效果
理想效果
...全文
997 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
冷静忍耐 2015-10-10
  • 打赏
  • 举报
回复
引用 12 楼 dqy0582 的回复:
[quote=引用 11 楼 u013466477 的回复:] 一、应该是刷新问题,你最小化后又起来,GraphicsView是会全刷,所以显示出来了。你试一下viewPort()->update()看行不行 二、setCursor(Qt::ClosedHandCursor);这个是QWidget子类才有的,所以你得用你的GraphicsView或者MainWindow来设置
多谢大神,我在x轴绘制函数中加入了update(),然后就解决了第一个问题,至于第二个问题还是以后慢慢解决吧[/quote] 第二个问题你直接用波形父对象设置鼠标样式就好了 parentWidget()->setCursor(Qt::ClosedHandCursor); 前提是构造波形时要传父对象进来。
dqy0582 2015-10-10
  • 打赏
  • 举报
回复
引用 11 楼 u013466477 的回复:
一、应该是刷新问题,你最小化后又起来,GraphicsView是会全刷,所以显示出来了。你试一下viewPort()->update()看行不行 二、setCursor(Qt::ClosedHandCursor);这个是QWidget子类才有的,所以你得用你的GraphicsView或者MainWindow来设置
多谢大神,我在x轴绘制函数中加入了update(),然后就解决了第一个问题,至于第二个问题还是以后慢慢解决吧
冷静忍耐 2015-10-09
  • 打赏
  • 举报
回复
一、应该是刷新问题,你最小化后又起来,GraphicsView是会全刷,所以显示出来了。你试一下viewPort()->update()看行不行 二、setCursor(Qt::ClosedHandCursor);这个是QWidget子类才有的,所以你得用你的GraphicsView或者MainWindow来设置
dqy0582 2015-10-09
  • 打赏
  • 举报
回复
附上我的波形和坐标轴代码,都是继承自QGraphicsItem和QObject,通过addItem()添加到窗口上
#include "wave1.h"

Wave1::Wave1(QObject *parent) : QObject(parent)
{
}

QRectF Wave1::boundingRect() const
{
    qreal adjust=2;
    return QRectF(0-adjust,0-adjust,100+adjust,100+adjust);
}

void Wave1::paint(QPainter *painter,const QStyleOptionGraphicsItem *option,QWidget *widget)
{
    QPainterPath path;
    path. moveTo(0,100);
    path. cubicTo(30,0,70,0,100,100);
    painter->setPen(QPen(Qt::blue,2));
    painter->setBrush( QBrush ( Qt :: green, Qt :: DiagCrossPattern));
    painter->drawPath(path);
}

void Wave1::mousePressEvent(QGraphicsSceneMouseEvent *event){
    if(event->button()==Qt::LeftButton)
    {
        setCursor(Qt::ClosedHandCursor);
    }
    if(event->button()==Qt::RightButton)
    {
    }
}

void Wave1::mouseMoveEvent(QGraphicsSceneMouseEvent *event){
    if(event->buttons()==Qt::LeftButton)
    {
        setPos(event->scenePos().x(),250);
    }
}
#include "xaxis.h"

XAxis::XAxis(QObject *parent) : QObject(parent)
{
}

void XAxis::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
        painter->setPen(QPen(Qt::black,2));
        painter->drawLine(0,2,500,2);
        painter->drawLine(498,0,500,2);
        painter->drawLine(498,4,500,2);
        painter->drawText(510,4,tr("x"));
}

QRectF XAxis::boundingRect() const
{
    qreal adjust=2;
    return QRectF(0-adjust,0-adjust,4+adjust,512+adjust);
}
dqy0582 2015-10-09
  • 打赏
  • 举报
回复
引用 8 楼 u013466477 的回复:
drawWidget里的layout整个变量都不要了

大神,我现在改变了思路,不用QLabel了,改用QGraphicsItem实现,也是通过改写鼠标事件,现在基本实现了功能,但是现在还有两个问题,第一个是我在滑动波形的时候坐标轴显示就会受到影响,把窗口最小化再打开又恢复好了,不知道是怎么回事;第二个问题是我想当鼠标左键选中波形的时候鼠标图标会变,用到setCursor(Qt::ClosedHandCursor),但是一编译这句就会报错,这又是什么情况?多谢大神耐心指导!



冷静忍耐 2015-09-30
  • 打赏
  • 举报
回复
drawWidget里的layout整个变量都不要了
冷静忍耐 2015-09-30
  • 打赏
  • 举报
回复
恩,编译出错是因为构造函数写错了,构造函数改成这样了吗?? Wave1_::Wave1_(QWidget *parent) : QLabel(parent) 是一样的,有了父对象就好了。 把那个drawWidget里的layout去掉,就你编译报错的后一句。 如果还无法显示,那你刷新一下试一下 wave1->update();或者show()一下
dqy0582 2015-09-30
  • 打赏
  • 举报
回复

图贴错了,那个wavelayout已经被我注释掉了,麻烦大神再帮我想想我可能出了什么问题,谢谢啊!
dqy0582 2015-09-30
  • 打赏
  • 举报
回复
引用 3 楼 u013466477 的回复:
添加到drawWidget,给label加个父对象就好了,如下:
wave1_=new Wave1(drawWidget);

然后y值你可以随便固定,例如你移动时每次都写y=100; 这是相对父对象drawWidget的坐标。
label->move(x, y); x是根据鼠标移动的距离,y固定就好。

多谢大神的指导,第二个将波形固定在坐标轴上的问题已经解决了,但是第一个添加的问题我试了一下编译会出错

后来我又修改了波形构造函数,Wave1::Wave1(QWidget ×w){},编译倒是不出错了,但是QLabel就无法显示了,因为我这个要画波形所以wave1,2是继承QLabel重写paintEvent,感觉添加起来跟一般QLabel不一样
冷静忍耐 2015-09-30
  • 打赏
  • 举报
回复
move(event->globalPos() .x() - dragPosition_.x(), y); y随意
冷静忍耐 2015-09-30
  • 打赏
  • 举报
回复
添加到drawWidget,给label加个父对象就好了,如下: wave1_=new Wave1(drawWidget); 然后y值你可以随便固定,例如你移动时每次都写y=100; 这是相对父对象drawWidget的坐标。 label->move(x, y); x是根据鼠标移动的距离,y固定就好。
dqy0582 2015-09-30
  • 打赏
  • 举报
回复
引用 1 楼 u013466477 的回复:
一、y轴坐标你不变就好了呀,固定Y轴坐标值,只改变x轴的值。 二、你把两个波形都加到wavelayout_这个布局里了?? 那两个波形不是都会被你布局吗,位置会被重新布局,所以不能把波形加到布局里
谢谢,但是如何固定y坐标值呢,可不可以再帮忙详细说明一下?还有我是用QLabel实现的绘图,如果不用布局的话又如何将QLabel添加到QWidget中呢?
冷静忍耐 2015-09-30
  • 打赏
  • 举报
回复
一、y轴坐标你不变就好了呀,固定Y轴坐标值,只改变x轴的值。 二、你把两个波形都加到wavelayout_这个布局里了?? 那两个波形不是都会被你布局吗,位置会被重新布局,所以不能把波形加到布局里

16,216

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧