【问题标题】:Qt GUI programming queryQt GUI编程查询
【发布时间】:2016-12-20 10:53:50
【问题描述】:

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

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

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

说了这个想法,我目前已经创建了带有工具箱和 QtGraphicsView 小部件的 GUI 布局。我能够访问各种形状的原始文件,并为 QtGraphicsView 小部件上添加的每个项目创建相应的克隆。我在这里面临的挑战是我无法对以下操作进行编码/编程,

1) 每当再次添加屏幕上已存在的项目的副本时,我无法为该项目创建特定的克隆。以下是从工具箱单击/添加此类项目到 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 小部件的相同形状的每个副本的克隆创建 ID?这很重要,因为当特定形状的副本被移动/碎片/删除时,该特定副本的 ID 将用于访问相应的 CLONE。

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

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

【问题讨论】:

  • 除此之外,我相信(我可能错了)为每个项目/形状创建 ID 的真正解决方案是为项目的每个选择创建一个事件。

标签: c++ qt user-interface oop


【解决方案1】:

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

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

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

【讨论】:

  • 您好 kuba Ober,感谢您的回答。实际上我真的无法理解你的答案(我不明白为什么我需要线程来实现这一点)。如果您能给我详细解释您的答案,那就太好了。谢谢你,干杯。
  • @VinokanthVelu 阻止文件访问可能需要任意时间。当您的应用程序等待文件系统响应时,GUI 被阻止。处理阻塞文件访问的唯一可移植方法是从 GUI 线程以外的线程执行它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 2016-09-29
  • 1970-01-01
  • 2010-09-28
相关资源
最近更新 更多