• 8675阅读
  • 7回复

[提问]qt的坐标转换问题!想破脑袋都没搞明白!!!!郁闷 [复制链接]

上一主题 下一主题
 

只看楼主 倒序阅读 楼主  发表于: 2011-08-12
各位大侠,WO 初学qt有个问题想了好几天都没想明白,
void CannonField::paintEvent( QPaintEvent * )  
{
    QPainter p( this );    //创建一个绘画工具来操作这个窗口部件
    p.setBrush( blue );   //定义画刷
    p.setPen( NoPen );    //定义画笔
    p.translate( 0, rect().bottom() );  //rect().bottom()获取矩形底部的y轴值   将矩形左下角转换成(0,0)
    p.drawPie( QRect(-35, -35, 70, 70), 0, 90*16 );    //为什么是-35呢?不懂,求解析(坐标系统)
    p.rotate( -ang );
    p.drawRect( QRect(33, -4, 15, 8) );
它不是转换坐标了吗,平时的坐标都是左上角开始的,它不是转到左下角了吗!但是为什么无端端多了个-35出来啊!左上角的横坐标是0,左下角的横坐标也应该是0啊!为什么它在-35的位置上画?但是-35显示出来确实刚刚在左下角,而(0,0)的话,会显示在它的右下方向!搞不懂啊!

离线roywillow

只看该作者 1楼 发表于: 2011-08-12
坐标的原点确实放到了左下角应该
但是别忘了y轴最终还是向下的……
整个区域应该是变成了x>0 y<0的象限了吧
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线roywillow

只看该作者 2楼 发表于: 2011-08-12
然后绘制饼形的时候是先指定一个矩形,在这个矩形的中心为圆心绘制一个饼
按照代码中的数据,这个圆心正好是在原点
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。

只看该作者 3楼 发表于: 2011-08-13
恩恩!有点明白了!但是,如果是在矩形的中心画的话,为什么圆心会在左下角呢?而且,当修改为p.drawPie( QRect(0, -35, 70, 70), 0, 90*16 )时,

也就是说转换后的坐标原点在上图圆心的下方35处,为什么圆心会被设置在哪里呢?
离线roywillow

只看该作者 4楼 发表于: 2011-08-13
因为这个QRect的左上角在-35, -35,是在这个区域的左边的,你在可见的绘制区域内看到的只是它右上象限的那四分之一;它的宽高是70,这样计算完它的中心正好是0,0。加上之前坐标平移,原点被移动到了左下角,所以圆心就在左下角了
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。

只看该作者 5楼 发表于: 2011-08-17
回 4楼(roywillow) 的帖子
因为这个QRect的左上角在-35, -35。这是为什么?它的源代码里没体现过。不是默认左上角是(0,0)的吗?代码如下:



lcdrange.h
/****************************************************************
**
** Definition of LCDRange class, Qt tutorial 8
**
****************************************************************/

#ifndef LCDRANGE_H
#define LCDRANGE_H

#include <qvbox.h>

class QSlider;


class LCDRange : public QVBox
{
    Q_OBJECT
public:
    LCDRange( QWidget *parent=0, const char *name=0 );

    int value() const;

public slots:
    void setValue( int );
    void setRange( int minVal, int maxVal );

signals:
    void valueChanged( int );

private:
    QSlider  *slider;
};


#endif // LCDRANGE_H

lcdrange.cpp
/****************************************************************
**
** Implementation of LCDRange class, Qt tutorial 8
**
****************************************************************/

#include "lcdrange.h"

#include <qslider.h>
#include <qlcdnumber.h>

LCDRange::LCDRange( QWidget *parent, const char *name )
        : QVBox( parent, name )
{
    QLCDNumber *lcd  = new QLCDNumber( 2, this, "lcd"  );
    slider = new QSlider( Horizontal, this, "slider" );
    slider->setRange( 0, 99 );
    slider->setValue( 0 );
    connect( slider, SIGNAL(valueChanged(int)),
             lcd, SLOT(display(int)) );
    connect( slider, SIGNAL(valueChanged(int)),
             SIGNAL(valueChanged(int)) );

    setFocusProxy( slider );
}

int LCDRange::value() const
{
    return slider->value();
}

void LCDRange::setValue( int value )
{
    slider->setValue( value );
}

void LCDRange::setRange( int minVal, int maxVal )
{
    if ( minVal < 0 || maxVal > 99 || minVal > maxVal ) {
      qWarning( "LCDRange::setRange(%d,%d)\n"
               "\tRange must be 0..99\n"
               "\tand minVal must not be greater than maxVal",
               minVal, maxVal );
      return;
    }
    slider->setRange( minVal, maxVal );
}


cannon.h
/****************************************************************
**
** Definition of CannonField class, Qt tutorial 8
**
****************************************************************/

#ifndef CANNON_H
#define CANNON_H

#include <qwidget.h>


class CannonField : public QWidget
{
    Q_OBJECT
public:
    CannonField( QWidget *parent=0, const char *name=0 );

    int angle() const { return ang; }
    QSizePolicy sizePolicy() const;

public slots:
    void setAngle( int degrees );

signals:
    void angleChanged( int );

protected:
    void paintEvent( QPaintEvent * );

private:
    int ang;
};


#endif // CANNON_H


cannon.cpp
/****************************************************************
**
** Implementation CannonField class, Qt tutorial 9
**
****************************************************************/

#include "cannon.h"
#include <qpainter.h>


CannonField::CannonField( QWidget *parent, const char *name )
        : QWidget( parent, name )
{
    ang = 45;
    setPalette( QPalette( QColor( 250, 250, 200) ) );
}


void CannonField::setAngle( int degrees )
{
    if ( degrees < 5 )
        degrees = 5;
    if ( degrees > 70 )
        degrees = 70;
    if ( ang == degrees )
        return;
    ang = degrees;
    repaint();
    emit angleChanged( ang );
}


void CannonField::paintEvent( QPaintEvent * )
{
    QPainter p( this );

    p.setBrush( blue );
    p.setPen( NoPen );

    p.translate( 0, rect().bottom() );
    p.drawPie( QRect(-35, -35, 70, 70), 0, 90*16 );
    p.rotate( -ang );
    p.drawRect( QRect(33, -4, 15, 8) );
}


QSizePolicy CannonField::sizePolicy() const
{
    return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
}



main.cpp
/****************************************************************
**
** Qt tutorial 9
**
****************************************************************/

#include <qapplication.h>
#include <qpushbutton.h>
#include <qlcdnumber.h>
#include <qfont.h>
#include <qlayout.h>

#include "lcdrange.h"
#include "cannon.h"


class MyWidget: public QWidget
{
public:
    MyWidget( QWidget *parent=0, const char *name=0 );
};


MyWidget::MyWidget( QWidget *parent, const char *name )
        : QWidget( parent, name )
{
    QPushButton *quit = new QPushButton( "&Quit", this, "quit" );
    quit->setFont( QFont( "Times", 18, QFont::Bold ) );

    connect( quit, SIGNAL(clicked()), qApp, SLOT(quit()) );

    LCDRange *angle = new LCDRange( this, "angle" );
    angle->setRange( 5, 70 );

    CannonField *cannonField = new CannonField( this, "cannonField" );

    connect( angle, SIGNAL(valueChanged(int)),
             cannonField, SLOT(setAngle(int)) );
    connect( cannonField, SIGNAL(angleChanged(int)),
             angle, SLOT(setValue(int)) );

    QGridLayout *grid = new QGridLayout( this, 2, 2, 10 );
    grid->addWidget( quit, 0, 0 );
    grid->addWidget( angle, 1, 0, Qt::AlignTop );
    grid->addWidget( cannonField, 1, 1 );
    grid->setColStretch( 1, 10 );

    angle->setValue( 60 );
    angle->setFocus();
}

int main( int argc, char **argv )
{
    QApplication::setColorSpec( QApplication::CustomColor );
    QApplication a( argc, argv );

    MyWidget w;
    w.setGeometry( 100, 100, 500, 355 );
    a.setMainWidget( &w );
    w.show();
    return a.exec();
}

离线roywillow

只看该作者 6楼 发表于: 2011-08-17
汗……
QRect(-35, -35, 70, 70)
这个东西执行完了不就是生成了一个左上角在(-35, -35),宽高为70的矩形了么……
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线wuleeemail

只看该作者 7楼 发表于: 2011-08-17
-35,-35包括70,这些值都是设计者自己定的,你完全可以修改,当然修改了这些值以后你画出来的图形就变了,这个需要你自己去试。
快速回复
限100 字节
 
上一个 下一个