//修改1——20170626
经过几周的奋斗,每天几个小时的研究,总算大致把书上的历程自己给实现了一遍,很多相似功能知识做了个例子,并没有做的全面,原因是一方面由于,时间的限制,18号就去上班了,但本职工作并不是和软件相关,软件只是个兴趣,以后没有这么多时间去研究,另一方面很多功能相似,操作都类似,就没有必要再去实施一遍了,这样比较省时间吧。下面是自己的研究的大致过程,简单的东西就没再写了:
1、搞懂QGraphicsItem中:boundingRect()和paint()成员函数的使用方式
void QGraphicsItem::paint()是在程序一开始就会直接调用,完成初始化的操作,不需要信号和槽的支持,可以理解为自动事件吧。。。。。
paint()为虚函数。
在本程序中的subclass中使用如下:
void NewItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
{
QPen pen(Qt::darkBlue);
if(option->state&QStyle::State_Selected)//画的时候,State_Selected——Used to indicate if a widget is selected.
{ //被选择时
pen.setStyle(Qt::DotLine);
pen.setWidth(2);
}
painter->setPen(pen);
painter->setBrush(Qt::white);
QRectF rect(x,y,45,30);
painter->drawRoundedRect(rect,rect.width()/2.0,rect.height()/2.0);
painter->setPen(Qt::darkGreen);
painter->drawText(rect,Qt::AlignCenter,text);
}
2、设置Item的几何位置。
方法一、通过paint()中的代码:
QRectF rect(x,y,45,30);
painter->drawRoundedRect(rect,rect.width()/2.0,rect.height()/2.0);
方法二、可以重载子类构造函数,用参数决定Item的位置:
NewItem::NewItem(qreal a,qreal b)
{
setFlags(ItemIsMovable|ItemIsSelectable);
x=a;
y=b;
text="text1";
}
3、另附好用的InputDialog:
QInputDialog inputdialog;
bool OK;
QString tmptext;
QString gettext=inputdialog.getText(event->widget(),"Edit Text","Enter new text:",QLineEdit::Normal,tmptext,&OK);
if(OK&&!text.isEmpty())//QInputDialog 好用!!!!!!!!!!!!!!!
{
text=gettext;
prepareGeometryChange();//大小、形状改变时调用
}
4、通过选项改变Item里面的数据
联系上文:当使用update()和prepareGeometryChange()是要调用:paint();故在paint()函数中设置传递变量就可以了:
painter->drawText(rect,Qt::AlignCenter,text);
5、菜单类
a)先设置动作,再创建菜单
b)菜单栏和工具栏的位置怎么弄???
1.菜单栏创建
直接使用 QMainWindow::menuBar()函数即可返回一个QMenuBar指针;
2.工具栏
定义了QToolBar *toolbar之后,不用new分配空间,直接用toolbar=addToolBar(" &New")
newaction->setIcon(QIcon("00.jpg")); 插入图片时别改图片的格式
6、图形化菜单
setIconSize(QSize())设置图标的大小。。
7、连线两个NewItem(画条直线)
QGraphicsItem::pos()返回的是Item的左上坐标。
具体的实现函数:
void lineItem::trackNodes()
{
QPoint f1(one->pos().x()+15,one->pos().y()+20);
QPoint f2(two->pos().x()+15,two->pos().y()+20);
setLine(QLineF(f1,f2));
}
8、数据存取
b)再读取,就可以恢复原状态
bool DiagramWindow::read()
{
QFile file("Graphics");
if(!file.open(QIODevice::ReadOnly)){
QMessageBox::warning(this,tr("QGraphhics"),tr("Cannot read file %1:\n%2.")
.arg(file.fileName()).arg(file.errorString()));
return false;
}
QDataStream in(&file);
in.setVersion(QDataStream::Qt_5_2);
quint32 magic;
in>>magic;
if(magic!=MagicNumber){
QMessageBox::warning(this,tr("QGraphics"),tr("The file is not a Spreadsheet file"));
return false;
}
qreal x;
qreal y;
while(!in.atEnd())
{
in>>x>>y;
NewItem *newitem=new NewItem(x,y);
newitem->setSelected(true);
scene->addItem(newitem);
view->setScene(scene);
update();
}
QApplication::restoreOverrideCursor();
return true;
}
bool DiagramWindow::save()
{
QFile file("Graphics");
if(!file.open(QIODevice::WriteOnly)){
QMessageBox::warning(this,"Graphics",tr("Cannot write file %1:\n%2.").arg(file.fileName())
.arg(file.errorString()));
return false;
}
QDataStream out(&file);
out.setVersion(QDataStream::Qt_5_2);
out<<quint32(MagicNumber);
QApplication::setOverrideCursor(Qt::WaitCursor);
QList<QGraphicsItem*>items=scene->items();
QMutableListIterator<QGraphicsItem*>i(items);
QGraphicsItem*tmp;
while(i.hasNext())
{
tmp=i.next();
out<<qreal(tmp->pos().x())<<qreal(tmp->pos().y());
}
QApplication::restoreOverrideCursor();
return true;
}
(注:不能直接把QGraphicsItem或者其subclass作为基本类型传递,但可以把相关数据,如位置,文本,等通过变量存取。)
新注:都可以传递,只要能够让函数获取所需数据的正确地址,传递什么类型的数据都不要紧——20170626
9、改变系统图标。。。改rc文件:
这是ICON 格式 名称
10、改变左上坐标this->setWindowIcon().
有参数的的构造函数的功能之一:
NewItem::NewItem(qreal a,qreal b)
为了传递参数。。。。。。
重新构造相应的NewItem,也就是有利于整个程序的信息交流。。。。。
11、坐标系的问题。
几何形状发生改变时,会发出resizeEvent这个事件设置resizeEvent();并写入以下内容即可:
void DiagramWindow::resizeEvent(QResizeEvent * event)
{
scene->setSceneRect(0,0,this->width(),this->height());
}
12、设置快捷键
delitem->setShortcut(Qt::Key_Delete);
13、error LNK2019: 无法解析的外部符号 "private: void __thiscall DiagramWindow::deleteitem(void)" (?deleteitem@DiagramWindow@@AAEXXZ),
该符号在函数 "private: static void __cdecl DiagramWindow::qt_static_metacall(class QObject *,enum QMetaObject::Call,int,void * *)" (?qt_static_metacall@DiagramWindow@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z) 中被引用
这种错误是由于 函数只有声明没有定义造成的。
14、最后得到如下视图的图形界面程序QGraphics1.0(有新建,连线,保存,删除,读取等功能):
再将之前的定时器结合在一起:
*总之问题还有很多,希望以后能够尽力做到2.0,3.0,4.0吧,以下是问题:
1、如何自己实现Items的选择和移动?
2、如何提高图标的清晰度?
3、资源管理相关知识是啥??
4、生成的EXE文件拖到桌面启动,无法工具栏的图标是怎么回事??
5、QGraphicsScene/View 的图层问题。
6、当QGraphicsScene的窗口大小变化时,怎么改变它的boundingrect()(可能没有??)使得已有的Items能够在
超出预设的范围scene=new QGraphicsScene(0,0,600,500)保存并读取其位置?以及如何当窗口大小改变时,如何
改变已有的Items的坐标和新生成的Items的坐标,即scene坐标系的0点永远在左上.(resizeEvent() 在QMainwindow
的subclass中能够被继承。)
void DiagramWindow::resizeEvent(QResizeEvent * event)
{
scene->setSceneRect(0,0,this->width(),this->height());
jishiqi->setGeometry(this->width()-130,this->height()-178,100,220);
};//这个可以解决问题6.
好了总结到此,希望以后做本职工作也要好好地努力,加油!!!