Qt GUI编程查询

时间:2015-07-13 16:58:19

标签: c++ qt user-interface oop

我目前正在使用Qt框架开发GUI应用程序。该应用程序是一个基本的“2D CAD”类似界面,商业2D CAD软件的复杂性较低。

这个想法是,有一个工具箱(如MS油漆),包含各种尺寸的矩形和方形(此GUI的目的是在柔性基板上设计RC电路设计。该软件将生成G代码(基本上是CNC机床的坐标信息,它将被送到CNC打印机,它根据产生的G代码信息在柔性基板上打印这些电路。每个矩形/方形包含已知目录中文本文件中“形状”的gcode(假设这是文本文件ORIGINAL)。文本文件中的这些G代码基于从GUI的坐标系的原点绘制的形状。当用户点击特定的正方形/矩形时,QtGraphicsView小部件的“origin”上会出现一个可移动/可拖动的形状,此动作会自动在已知目录中创建一个新文本文件,该文件将复制文本文件中的所有G代码(来自ORIGINAL文本文件)包含在原点绘制的特定形状的原始G代码(假设此文本文件为CLONE)。由于这些形状是可移动的,当用户在屏幕上拖动/移动特定项目时,软件应该能够访问为该特定项目创建的CLONE文件,并通过以下方式编辑/偏移从ORIGINAL复制的坐标:形状的当前坐标位置。

例如,当用户首次单击形状并且形状出现在QtGraphicsView小部件的原点上时,这将为此项创建一个CLONE,其中包含此形状的ORIGINAL中此形状的坐标/ G代码。然后用户将项目移动到(100,-65)。因此,用户的这个动作通过新坐标(100,-65)偏移之前创建的CLONE的每个坐标信息,并保存CLONE文本文件。此外,假设用户再次从工具箱中添加相同的“形状”,这导致QtGraphicsView小部件的原点出现相同的“形状”。在这种情况下,QtGraphicsView小部件上有两个相同“形状”的副本。当第二个动作发生时,GUI应该为这个相同形状的副本生成一个新的CLONE文件,并且当移动/拖动相应的形状副本时,应该执行该CLONE的编辑/偏移坐标。同样,当从QtGraphicsView小部件中删除特定项时,也应该从目录中删除该项的相应CLONE。此外,GUI应该能够根据特定的ORIGINAL文件为工具箱上提供的多种形状生成CLONES。

说完这个想法后,我现在用它的工具箱和QtGraphicsView小部件创建了GUI的布局。我能够访问各种形状的ORIGINAL文件,并为QtGraphicsView小部件上添加的每个项目创建相应的CLONES。我在这里面临的挑战是我无法对以下行为进行编码/编程,

1)每当再次添加屏幕上已存在的项目的副本时,我无法为此项目创建特定的CLONE。以下是从工具箱中单击/添加一个此类项目到QtGraphicsView小部件的代码。

void MainWindow::on_toolButton_3_clicked()

{
    //32 Ohms resitance (base square resistor)

    ui->graphicsView->setScene(scene);
    QBrush blackBrush(Qt::darkGray);
    QPen outlinePen(Qt::black);
    outlinePen.setWidth(2);

    rect = scene->addRect(-100,-100,20,20,outlinePen,blackBrush);
    rect->setFlag(QGraphicsItem::ItemIsSelectable);
    rect->setFlag(QGraphicsItem::ItemIsMovable);
    text = scene->addText("32Ohms");
    text->setFlag(QGraphicsItem::ItemIsMovable);
    text->setFlag(QGraphicsItem::ItemIsSelectable);

    QFile file_in("/Users/vinokanthvelu/Desktop/Graphite Circuitry printer/GUI/Gcodes/32_ohm_in.rtf");
    QFile file_out("/Users/vinokanthvelu/Desktop/Graphite Circuitry printer/GUI/Gcodes/output.txt");

    if(file_in.exists() == true)
    {
        QMessageBox::information(this,"Found","File exists");
    }
    else
    {
        QMessageBox::information(this,"Error","Not found");
    }

    if(!file_in.open(QIODevice::ReadOnly|QIODevice::Text))
    {
        QMessageBox::information(this,"Error","file_in ERROR");
        return;
    }

    QTextStream in(&file_in);
    while(!file_in.atEnd())
    {
        QString line = in.readAll();
        if(!file_out.open(QIODevice::WriteOnly|QIODevice::Text))
        {
            QMessageBox::information(this,"Error","file_out ERROR");
            return;
        }
        QTextStream out(&file_out);

        //Copy the gcodes from the source file to output file
        out << line << endl;
    }
}

这是因为创建副本时,此操作会尝试创建与同一项的上一个副本的CLONE同名的CLONE。这不是什么要求。

2)如何为添加到QtGraphicsView小部件的每个相同形状的重复项的CLONES创建ID?这很重要,因为当移动/分段/删除特定形状的副本时,该特定副本的ID用于访问相应的CLONE。

3)除了我想为几个形状的各种副本创建CLONES以跟踪QtGraphicsView小部件中相应ORIGINALS的所有项的坐标位置之外,还有其他有效的方法来实现吗?

对不起,很长的帖子。我想提供一个清晰的详细问题,以便更容易掌握和解决问题(我是Qt和面向对象编程的新手)。

1 个答案:

答案 0 :(得分:0)

作为绘图画布上的操作的直接结果,以阻塞方式访问文件通常是个坏主意。用户体验非常糟糕。

您应该在程序启动时在后台线程中预加载所有预定义的形状,然后将它们作为数据结构进行维护。您应该只在用户想要保存数据时保存克隆的形状,或者自动保存,但也应该在单独的线程中完成,并进行适当的短期锁定。文件编写器应该只锁定足够长的时间来复制数据,然后在执行任何文件访问之前释放锁。

这会使ID生成变得微不足道:在将形状写入磁盘时,可以生成唯一的顺序ID。我还质疑将所有克隆的形状写入单个文件的必要性。理想情况下,如果您的打印机支持它,您应该只将所有使用过的形状写为RS-274X宏,然后为每个克隆实例化宏。这将最小化输出文件的大小,并使其保留原始设计的一些结构。 RS-274X可能就是您唯一的设计文件格式。