- 有时候需要暂时停止某个控件发射信号(比如下拉框combobox添加数据的时候会触发当前元素改变信号),有多种处理,推荐用 blockSignals 方法。
disconnect(ui->cbox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_cbox_currentIndexChanged(int)));
for (int i = 0; i <= 100; i++) {
ui->cbox->addItem(QString::number(i));
}
connect(ui->cbox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_cbox_currentIndexChanged(int)));
ui->cbox->blockSignals(true);
for (int i = 0; i <= 100; i++) {
ui->cbox->addItem(QString::number(i));
}
ui->cbox->blockSignals(false);
- 项目代码文件数量如果很多的话,全部包含在pro项目文件中会显得非常凌乱,甚至滚动条都要拉好久,有两个方法可以处理的更好,推荐方法2。
HEADERS += *.h
SOURCES += *.cpp
include($$PWD/ui/ui.pri)
INCLUDEPATH += $$PWD/ui
- 在网络通信中,无论是tcp客户端还是udp客户端,其实都是可以绑定网卡IP和端口的,很多人只知道服务端可以指定网卡监听端口。客户端如果没有绑定通信端口则由客户端所在的操作系统随机递增分配的,这里为啥这么强调,因为无数人,甚至不乏一些多年经验的新时代农名工,以为客户端的端口是服务端分配的,因为他们看到在服务端建立连接后可以打印出不同的端口号。网络通信的双方自己决定自己要用什么端口,服务器端只能决定自己监听的是哪个端口,不能决定客户端的端口,同理客户端也只能决定自己的端口。端口随机分配一般是按照顺序递增的,比如先是45110端口,连接重新建立就用45111端口,只要端口没被占用就这样递增下去,所以很多人会问是否可以复用一些端口,不然端口一直这样频繁的分配下去不妥,甚至有些特定的场景和需求也是会要求客户端绑定网卡和端口来和服务器通信的。
QTcpSocket *socket = new QTcpSocket(this);
socket->abort();
socket->bind(QHostAddress("192.168.1.2"), 6005);
socket->connectToHost("192.168.1.3", 6000);
qDebug() << socket->localAddress() << socket->localPort();
qDebug() << socket->peerAddress() << socket->peerPort() << socket->peerName();
QUdpSocket *socket = new QUdpSocket(this);
if (socket->localPort() != 6005) {
socket->abort();
socket->bind(QHostAddress("192.168.1.2"), 6005);
}
socket->writeDatagram(buffer, QHostAddress("192.168.1.3"), 6000);
TcpSocket *socket = new TcpSocket(this);
socket->setLocalAddress(QHostAddress("192.168.1.2"));
socket->setLocalPort(6005);
- 关于网络通信,tcp和udp是两种不同的底层的网络通信协议,两者监听和通信的端口互不相干的,不同的协议或者不同的网卡IP地址可以用相同的端口。之前有个人说他的电脑居然可以监听一样的端口进行通信,颠覆了他以前的认知,书上说的明明是不可以相同端口的,后面远程一看原来选择的不同的网卡IP地址,当然可以的咯。
- tcp对网卡1监听了端口6000,还可以对网卡2监听端口6000。
- tcp对网卡1监听了端口6000,udp对网卡1还可以继续监听端口6000。
- tcp对网卡1监听了端口6000,在网卡1上其他tcp只能监听6000以外的端口。
- udp协议也是上面的逻辑。
- 开源的图表控件QCustomPlot很经典,在曲线数据展示这块性能彪悍,总结了一些容易忽略的经验要点。
- 可以将XY轴对调,然后形成横向的效果,无论是曲线图还是柱状图,分组图、堆积图等,都支持这个特性。
- 不需要的提示图例可以调用 legend->removeItem 进行移除。
- 两条曲线可以调用 setChannelFillGraph 设置合并为一个面积区域。
- 可以关闭抗锯齿 setAntialiased 加快绘制速度。
- 可以设置不同的线条样式(setLineStyle)、数据样式(setScatterStyle)。
- 坐标轴的箭头样式可更换 setUpperEnding。
- 可以用 QCPBarsGroup 实现柱状分组图,这个类在官方demo中没有,所以非常容易忽略。
QCPAxis *yAxis = customPlot->yAxis;
QCPAxis *xAxis = customPlot->xAxis;
customPlot->xAxis = yAxis;
customPlot->yAxis = xAxis;
customPlot->legend->removeItem(1);
customPlot->graph(0)->setChannelFillGraph(customPlot->graph(1));
customPlot->graph()->setAntialiased(false);
customPlot->setNoAntialiasingOnDrag(true);
customPlot->graph(0)->setData();
customPlot->graph(0)->data()->set();
customPlot->graph()->setLineStyle(QCPGraph::lsLine);
customPlot->graph()->setScatterStyle(QCPScatterStyle::ssDot);
customPlot->graph()->setScatterStyle(QCPScatterStyle(shapes.at(i), 10));
customPlot->graph()->setScatterStyle(QCPScatterStyle(QPixmap("./sun.png")));
QPainterPath customScatterPath;
for (int i = 0; i < 3; ++i) {
customScatterPath.cubicTo(qCos(2 * M_PI * i / 3.0) * 9, qSin(2 * M_PI * i / 3.0) * 9, qCos(2 * M_PI * (i + 0.9) / 3.0) * 9, qSin(2 * M_PI * (i + 0.9) / 3.0) * 9, 0, 0);
}
customPlot->graph()->setScatterStyle(QCPScatterStyle(customScatterPath, QPen(Qt::black, 0), QColor(40, 70, 255, 50), 10));
customPlot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
customPlot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);
customPlot->axisRect()->setBackground(QPixmap("./solarpanels.jpg"));
customPlot->graph(0)->setBrush(QBrush(QPixmap("./balboa.jpg")));
customPlot->setBackground(QBrush(gradient));
customPlot->xAxis->grid()->setZeroLinePen(Qt::NoPen);
customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables);
QCPBarsGroup *group = new QCPBarsGroup(customPlot);
QList<QCPBars*> bars;
bars << fossil << nuclear << regen;
foreach (QCPBars *bar, bars) {
bar->setWidth(bar->width() / bars.size());
group->append(bar);
}
group->setSpacing(2);
|