QT 使用注意事项

1.   qt 里面的网络调用都是异步的,同步 http 请求的例子如下:
bool WebUtil::HttpPost(const QUrl& url, const QByteArray& post_data, QByteArray* resp) {
  QNetworkRequest req;
  req.setUrl(QUrl(url));
  req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
  QNetworkAccessManager m;
  bool ret = false;
  QNetworkReply* reply = nullptr;
  do {
    reply = m.post(req, post_data);
    QEventLoop loop;
    QTimer timer;
    timer.setSingleShot(true);
    QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    QObject::connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), &loop, SLOT(quit()));
    timer.start(3*1000);
    qDebug() << "enter main_loop";
    loop.exec();
    qDebug() << "exit main_loop";
    if (!timer.isActive()) {
      QObject::disconnect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
      *resp = "time-out";
      break;
    }
    timer.stop();
    if (reply->error() == QNetworkReply::NoError) {
      if (resp != nullptr) {
        *resp = reply->readAll();
      }
      ret = true;
    } else {
      qDebug() << "error to http post: " << reply->errorString();
      if (resp != nullptr) {
        *resp = reply->errorString().toLatin1();
      }
    }
  } while (false);
  if (reply != nullptr) {
    delete reply;
  }
  return ret;
}

在loop.exec() 的时候,可能切换到别的线程去了


2.  QT 里面好多函数不能跨线程直接通讯,可以使用 PostEvent 来达到这个目的,代码如下:

// 定义一个事件
const QEvent::Type WS_SEND = static_cast<QEvent::Type>(QEvent::User + 100);
class WsSendEvent : public QEvent {
public:
  WsSendEvent(const QByteArray& data) : QEvent(WS_SEND) {
    data_ = data;
  }
  const QByteArray& GetData() {
    return data_;
  }
private:
  QByteArray data_;
};

在目的对象里面,继承 QObject, 重写:
  bool event(QEvent* event) {
    if (event->type() == WS_SEND) {
      WsSendEvent* me = static_cast<WsSendEvent*>(event);
      ws_->sendMessage(me->GetData());
      return true;
    }
    return QObject::event(event);
  }

在另外一线程里发消息,通知该线程处理:
QCoreApplication::postEvent(this, new WsSendEvent(qba));


3.  关于 DeleteLater
 如果不是做 GUI 相关的,尽量不要使用,直接 delete 好了。


4. ESC/POS  图片打印, 网上看了好多资料,下面给出一个实际可用的【图片之间不会出现空白行】

bool Printer::PrintImage1(const QImage& img) {
  bool pr = false;
  do {
    QByteArray cmd;
    QTcpSocket socket;
    socket.connectToHost(host_, port_);
    qDebug() << "connect print: " << host_ << ":" << port_;
    bool conn_ret = socket.waitForConnected(20*1000);
    if (conn_ret == false) {
      break;
    }

    // just print image !!
    int w = img.width();
    int h = img.height();
    int line_height = 24;
    int wl = w % 256;
    int wh = w / 256;
    // 复位
    cmd.clear();
    cmd.append(0x1b);
    cmd.append(0x40);
    SendData(&socket, cmd);


    qDebug() << "img_h: " << h << ", img_w: " << w;
    // print 24 height every time !!
    bool send_data_succ = true;
    int32_t seg_cnt = (h + line_height - 1)/line_height;
    for (int li = 0; li < seg_cnt; ++li) {
      char raw_data[w*3] = {0};
      int batch_height = (h - li*line_height);
      if(batch_height > line_height) {
        batch_height = line_height;
      }

      cmd.clear();
      cmd.append((char)0x1B);
      cmd.append((char)0x2A);
      cmd.append((char)0x21);
      cmd.append((char)wl);
      cmd.append((char)wh);
      // sub line!!
      for (int hp = 0; hp < batch_height; hp++) {
        for (int wp = 0; wp < w; ++wp) {
          int image_y = li*line_height + hp;
          int image_x = wp;
          int print_value = (qBlue(img.pixel(image_x, image_y)) < 0xff) ? 1 : 0;
          int data_index = wp*3 + (hp/8);
          int bit_index = (7 - hp%8);
          raw_data[data_index] |= (print_value << bit_index);
        }
      }
      for (int i = 0; i < 3*w; ++i) {
        cmd.append(raw_data[i]);
      }
      if (!SendData(&socket, cmd)) {
        send_data_succ = false;
        break;
      }
      // 进纸并进纸 24 个点
      cmd.clear();
      cmd.append(0x1b);
      cmd.append(0x4a);
      cmd.append(24);
      if (!SendData(&socket, cmd)) {
        send_data_succ = false;
        break;
      }
    }

    // 打印并进纸 4 行
    cmd.append(0x1b);
    cmd.append(0x64);
    cmd.append(4);
    SendAndClear(&socket, &cmd);


    // 走纸张并切纸, 方式为 1
    cmd.clear();
    cmd.append((char)0x1D);
    cmd.append((char)0x56);
    cmd.append((char)0x01);
    if (!SendData(&socket, cmd)) {
      qDebug() << "cut paper error !!";
      break;
    }
    pr = true;
    socket.close();
  } while (false);
  return pr;
}


5.  非 gui 使用 gui 的东西,怎么办呢? 

  int image_w = 576;
  int image_h = (24+4)*op.dish_info_size() + 48;
  QImage img(image_w, image_h, QImage::Format_Grayscale8);
  img.fill(Qt::GlobalColor::white);
  QPainter painter(&img);
  //painter.setRenderHint(QPainter::TextAntialiasing, true);
  QFont font("宋体");
  font.setBold(true);
  int top = 0;
  int line_height;
  QRect r;

  // title;
  top += 0;
  line_height = 48;
  font.setPixelSize(line_height);
  painter.setFont(font);
  r = QRect(0, top, image_w, line_height);
  top += line_height + 4;
  painter.drawText(r, Qt::AlignVCenter|Qt::AlignHCenter, QString::fromStdString(op.table()));

  line_height = 24;
  font.setPixelSize(line_height);
  painter.setFont(font);
  int need_height;
  int x_offset;
  int part_w;
  for (int i = 0; i < op.dish_info_size(); ++i) {
    const server::OrderPrepare_DishInfo & di = op.dish_info(i);
    // every field !!
    x_offset = 0;
    need_height = line_height;
    part_w = image_w/2;
    r = QRect(x_offset, top, part_w, need_height);
    painter.drawText(r, Qt::AlignLeft|Qt::AlignTop, QString::fromStdString(di.dish_name()));

    x_offset += part_w;
    part_w = image_w/4;
    need_height = line_height;
    r = QRect(x_offset, top, part_w, need_height);
    painter.drawText(r, Qt::AlignRight|Qt::AlignTop, QString::fromStdString(di.dish_count()));

    x_offset += part_w;
    part_w = image_w/4;
    need_height = line_height;
    r = QRect(x_offset, top, part_w, need_height);
    painter.drawText(r, Qt::AlignRight|Qt::AlignTop, QString::fromStdString(di.dish_comment()));

    top += need_height + 4;
  }

  std::string nm = std::to_string(QDateTime::currentDateTime().toTime_t()).append(".png");
  img.save(QString::fromStdString(nm));
  PrintImage1(img);
  return true;
这样 img 是可以直接用的, 需要使用 QAppication

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值