主要代码如下:
MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
QStringList qList;
qList << "15" << "16" << "17" << "18" << "19" << "20" << "21"\
<< "22" << "23" << "24";
ui.comboBox->addItems(qList);
ui.numberLabel->setAlignment(Qt::AlignCenter);
qList.clear();
qList << tr("用户名") << tr("IP地址");
ui.tableWidget->setColumnCount(2);
ui.tableWidget->setHorizontalHeaderLabels (qList);
ui.tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
connect(ui.textEdit,SIGNAL(currentCharFormatChanged(const QTextCharFormat&)),\
this,SLOT(on_currentCharFormatChanged(const QTextCharFormat&)));
connect(ui.tableWidget,SIGNAL(doubleClicked (const QModelIndex & )),\
this,SLOT(on_doubleClicked(const QModelIndex &)));
this->setWindowTitle(tr("聊天程序"));
port = 20000;
hostName = QHostInfo::localHostName();
address = getIP();
chatUSocket = new QUdpSocket(this);
chatUSocket->bind(port,QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
connect(chatUSocket,SIGNAL(readyRead()),this,SLOT(processMessage()));
sendFileDlg = new SendFileDlg(this);
connect(sendFileDlg,SIGNAL(sendFile(const STU_FILE&)),this,SLOT(getFile(const STU_FILE&)));
STU_HEADER heard = {MainWindow::LOGIN,hostName,address};
sendMessage(Message(heard));
qDebug() << "Date:" << QDate::currentDate();
}
MainWindow::~MainWindow()
{
chatUSocket->close();
delete chatUSocket;
delete sendFileDlg;
}
void MainWindow::on_fontComboBox_currentFontChanged( const QFont & font )
{
ui.textEdit->setCurrentFont(font);
ui.textEdit->setFocus();
}
void MainWindow::on_comboBox_currentIndexChanged ( const QString arg )
{
ui.textEdit->setFontPointSize(arg.toDouble());
ui.textEdit->setFocus();
}
void MainWindow::on_boldToolBtn_clicked( bool checked )
{
if(checked)
ui.textEdit->setFontWeight(QFont::Bold);
else
ui.textEdit->setFontWeight(QFont::Normal);
ui.textEdit->setFocus();
}
void MainWindow::on_italicToolBtn_clicked( bool checked )
{
ui.textEdit->setFontItalic(false);
ui.textEdit->setFocus();
}
void MainWindow::on_underlineToolBtn_clicked( bool checked )
{
ui.textEdit->setFontUnderline(checked);
ui.textEdit->setFocus();
}
void MainWindow::on_colorToolBtn_clicked()
{
QColorDialog *colorDlg = new QColorDialog(this);
colorDlg->open();
connect(colorDlg,SIGNAL(colorSelected(const QColor&)),this,SLOT(on_colorSelected(const QColor&)));
}
void MainWindow::on_sendToolBtn_clicked()
{
int row = ui.tableWidget->currentRow();
if (row == -1)
{
QMessageBox::warning(this,tr("提示"),tr("请选则发送用户"),QMessageBox::Ok);
return;
}
sendFileDlg->show();
sendFileDlg->init();
}
void MainWindow::on_saveToolBtn_clicked()
{
}
void MainWindow::on_clearToolBtn_clicked()
{
ui.textBrowser->clear();
}
void MainWindow::on_sendPushBtn_clicked()
{
QString msg;
msg = ui.textEdit->toPlainText();
if ("" == msg)
{
QMessageBox::warning(this,tr("警告"),tr("发送内容不能为空"),QMessageBox::Ok);
return;
}
STU_HEADER heard = {MainWindow::MESSAGE,hostName,address};
STU_MSG stMsg = {1,msg};
sendMessage(Message(heard,stMsg));
ui.textEdit->clear();
}
void MainWindow::on_exitPushBtn_clicked()
{
STU_HEADER heard = {MainWindow::LEAVE,hostName,address};
sendMessage(Message(heard));
close();
}
void MainWindow::processMessage()
{
if (chatUSocket->hasPendingDatagrams())
{
QByteArray dataGram;
dataGram.resize(chatUSocket->pendingDatagramSize());
QDataStream in(&dataGram,QIODevice::ReadOnly);
chatUSocket->readDatagram(dataGram.data(),dataGram.size());
Message msg;
in >> msg;
switch (msg.heard.msgType)
{
case LOGIN:
on_login(msg);
break;
case LEAVE:
on_leave(msg);
break;
case MESSAGE:
on_message(msg);
break;
case FILENAME:
on_file(msg);
break;
case REFUSE:
on_refuse(msg);
break;
default:
break;
}
}
}
void MainWindow::sendMessage(Message& msg)
{
QByteArray dataGram;
QDataStream out(&dataGram,QIODevice::WriteOnly);
out << msg;
chatUSocket->writeDatagram(dataGram,QHostAddress::Broadcast,port);
}
void MainWindow::on_login(Message& msg)
{
qDebug() << tr("处理登入消息");
bool bEmpty = ui.tableWidget->findItems(msg.heard.sndHosName,Qt::MatchExactly).isEmpty();
if (bEmpty)
{
QTableWidgetItem* hsNaItem = new QTableWidgetItem(msg.heard.sndHosName);
QTableWidgetItem* addrItem = new QTableWidgetItem(msg.heard.sndAddr);
ui.tableWidget->insertRow(0);
ui.tableWidget->setItem(0,0,hsNaItem);
ui.tableWidget->setItem(0,1,addrItem);
}
int lineNum = ui.tableWidget->rowCount();
ui.numberLabel->setText(tr("在线人数:%1").arg(lineNum));
}
void MainWindow::on_leave(Message& msg)
{
qDebug() << tr("处理退出消息");
QList<QTableWidgetItem*> listItem = ui.tableWidget->findItems(msg.heard.sndHosName,Qt::MatchExactly);
foreach(QTableWidgetItem* item,listItem)
{
int row = item->row();
ui.tableWidget->removeRow(row);
}
int lineNum = ui.tableWidget->rowCount();
ui.numberLabel->setText(tr("在线人数:%1").arg(lineNum));
}
const QString MainWindow::getIP()
{
QList<QHostAddress> addrList = QNetworkInterface::allAddresses ();
foreach(QHostAddress addr,addrList){
if (addr.protocol() == QAbstractSocket::IPv4Protocol)
return addr.toString();
}
return NULL;
}
void MainWindow::on_message(Message& msg)
{
if (1 == msg.msg.type)
{
ui.textBrowser->setTextColor(Qt::blue);
ui.textBrowser->append("[" + msg.heard.sndHosName + "]");
ui.textBrowser->append(msg.msg.content);
}
if (0 == msg.msg.type && msg.heard.recAddr==address)
{
if (!oneChatDlgList.contains(locOneChatDlg) || !chatList.contains(msg.heard.sndAddr))
{
chatList.append(msg.heard.sndAddr);
locOneChatDlg = new OneChatDlg(this);
oneChatDlgList.append(locOneChatDlg);
connect(locOneChatDlg,SIGNAL(sndMsgToMainWnd(const QString&)),this,SLOT(getOneChatMsg(const QString&)));
connect(locOneChatDlg,SIGNAL(closeWindow(OneChatDlg*)),this,SLOT(delOneChatDlg(OneChatDlg*)));
locOneChatDlg->setModal(false);
locOneChatDlg->show();
locOneChatDlg->setWindowTitle(msg.heard.sndAddr);
QList<QTableWidgetItem*> qList = ui.tableWidget->findItems(msg.heard.sndAddr,Qt::MatchExactly);
if(qList.size() > 0)
ui.tableWidget->setCurrentCell(qList.at(0)->row(),qList.at(0)->column());
}
locOneChatDlg->setWindowTitle(msg.heard.sndHosName);
locOneChatDlg->textBro()->append("[" + msg.heard.sndHosName + "]");
locOneChatDlg->textBro()->append(msg.msg.content);
}
}
void MainWindow::on_colorSelected( const QColor& color)
{
ui.textEdit->setTextColor(color);
ui.textEdit->setFocus();
}
void MainWindow::on_file(Message& msg)
{
qDebug() << tr("处理文件信息");
if (msg.heard.recAddr == getIP())
{
int iResult = QMessageBox::question(this,tr("提示"),\
tr("是否接收来自:%1的文件:%2?").arg(msg.heard.sndHosName).arg(msg.file.name),\
QMessageBox::Ok|QMessageBox::Cancel);
if (iResult == QMessageBox::Ok)
{
ReceiveFileDlg *rcvFileDlg = new ReceiveFileDlg(this);
rcvFileDlg->show();
rcvFileDlg->setMsg(msg);
}
else
{
STU_HEADER heard = {MainWindow::REFUSE,hostName,address,msg.heard.sndHosName,\
msg.heard.sndAddr};
sendMessage(Message(heard));
}
}
}
void MainWindow::on_refuse(Message& msg)
{
if (msg.heard.recAddr == getIP())
{
QMessageBox::information(this,tr("提示"),tr("%1拒绝接收你的文件").arg(msg.heard.sndHosName),\
QMessageBox::Ok);
}
}
void MainWindow::getFile( const STU_FILE& stFile)
{
QString recHsname,recAddr;
QTableWidgetItem *item;
int row = ui.tableWidget->currentRow();
item = ui.tableWidget->item(row,0);
recHsname = item->text();
item = ui.tableWidget->item(row,1);
recAddr = item->text();
STU_HEADER heard = {MainWindow::FILENAME,hostName,address,\
recHsname,recAddr};
sendMessage(Message(heard,stFile));
}
void MainWindow::on_currentCharFormatChanged( const QTextCharFormat& f)
{
ui.textBrowser->setFont(f.font());
}
void MainWindow::on_doubleClicked( const QModelIndex & index)
{
QString recHsname;
QTableWidgetItem *item;
int row = ui.tableWidget->currentRow();
item = ui.tableWidget->item(row,0);
recHsname = item->text();
OneChatDlg *oneChatdlg = new OneChatDlg(this);
connect(oneChatdlg,SIGNAL(sndMsgToMainWnd(const QString&)),this,SLOT(getOneChatMsg(const QString&)));
connect(oneChatdlg,SIGNAL(closeWindow(OneChatDlg*)),this,SLOT(delOneChatDlg(OneChatDlg*)));
oneChatdlg->setModal(false);
oneChatdlg->show();
oneChatdlg->setWindowTitle(recHsname);
oneChatDlgList.append(oneChatdlg);
}
void MainWindow::getOneChatMsg(const QString& msg)
{
QString recHsname,recAddr;
QTableWidgetItem *item;
int row = ui.tableWidget->currentRow();
item = ui.tableWidget->item(row,0);
recHsname = item->text();
item = ui.tableWidget->item(row,1);
recAddr = item->text();
STU_HEADER heard = {MainWindow::MESSAGE,hostName,address,recHsname,recAddr};
STU_MSG stMsg = {0,msg};
sendMessage(Message(heard,stMsg));
}
void MainWindow::delOneChatDlg(OneChatDlg* dlg)
{
QString title = dlg->windowTitle();
oneChatDlgList.removeOne(dlg);
if(chatList.contains(title))
chatList.removeOne(title);
}