├── .gitignore ├── README.md ├── include ├── ChatWidget.h ├── MainWindow.h └── OnlineList.h ├── res ├── images │ ├── bin_empty.png │ ├── fonts.png │ ├── insertimage.png │ ├── logo.png │ ├── save.png │ ├── textbold.png │ ├── textcolor.png │ ├── textitalic.png │ └── textunderline.png └── language │ └── qt_zh_CN.qm ├── resource.qrc ├── src ├── ChatWidget.cpp ├── MainWindow.cpp ├── OnlineList.cpp └── main.cpp └── xylchat.pro /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | *.dylib 9 | 10 | # Program Files 11 | Makefile 12 | moc_* 13 | qrc_* 14 | ui_* 15 | *.user 16 | tags 17 | xylchat 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 一个局域网内发消息的聊天室小程序。 2 | -------------------------------------------------------------------------------- /include/ChatWidget.h: -------------------------------------------------------------------------------- 1 | // ===================================================================================== 2 | // 3 | // Filename: ChatWidget.h 4 | // 5 | // Description: 聊天显示控件的声明 6 | // 7 | // Version: 1.0 8 | // Created: 2013年06月03日 18时43分32秒 9 | // Revision: none 10 | // Compiler: g++ 11 | // 12 | // Author: Hurley (LiuHuan), liuhuan1992@gmail.com 13 | // Company: Class 1107 of Computer Science and Technology 14 | // 15 | // ===================================================================================== 16 | 17 | #ifndef CHATWIDGET_H_ 18 | #define CHATWIDGET_H_ 19 | 20 | #include 21 | #include 22 | 23 | class QVBoxLayout; 24 | class QHBoxLayout; 25 | class QSplitter; 26 | class QTextBrowser; 27 | class QTextEdit; 28 | class QListView; 29 | class QPushButton; 30 | class OnlineList; 31 | 32 | // 用户消息类型的枚举变量 33 | enum MessageType { 34 | Message = 0, 35 | UserLogin = 1, 36 | Userleft = 2, 37 | AskWhoOnline = 3, 38 | IamOnline = 4 39 | }; 40 | 41 | class ChatWidget : public QWidget 42 | { 43 | Q_OBJECT 44 | public: 45 | ChatWidget(); 46 | ChatWidget(OnlineList *onlineList); 47 | ~ChatWidget(); 48 | 49 | void createWidget(); 50 | void createNetLink(); 51 | 52 | protected: 53 | void closeEvent(QCloseEvent *); 54 | bool eventFilter(QObject *target, QEvent *event); 55 | 56 | public slots: 57 | void fontSize(); 58 | void fontBold(); 59 | void fontItalic(); 60 | void fontUnderline(); 61 | void fontColor(); 62 | void insertImage(); 63 | void saveChatInfo(); 64 | void clearChatInfo(); 65 | void sendSlot(); 66 | 67 | // 发送数据包 68 | void sendMessage(MessageType type, QString ipAddr = ""); 69 | // 接收处理数据包 70 | void recvMessage(); 71 | 72 | private: 73 | // 获取IP地址 74 | QString getIP(); 75 | // 获取用户名 76 | QString getUserName(); 77 | // 获取输入信息 78 | QString getMessage(); 79 | 80 | // 聊天框添加一条聊天信息 81 | void addUserChatInfoOnce(QString username, QString message); 82 | 83 | // 处理用户上线 84 | void disUserLogin(QString username, QString hostname, QString ipAddr); 85 | // 处理用户离线 86 | void disUserLeft(QString username, QString hostname, QString ipAddr); 87 | 88 | private: 89 | QUdpSocket *sockServer; 90 | qint16 listen_port; 91 | 92 | OnlineList *onlineList; 93 | 94 | QVBoxLayout *mainVBoxLayout; 95 | QHBoxLayout *toolHBoxLayout; 96 | QHBoxLayout *buttonHBoxLayout; 97 | 98 | QTextBrowser *chatText; 99 | QTextEdit *sendText; 100 | 101 | QPushButton *closeButton; 102 | QPushButton *sendButton; 103 | 104 | QPushButton *fontSizeButton; 105 | QPushButton *fontBoldButton; 106 | QPushButton *fontItalicButton; 107 | QPushButton *fontUnderlineButton; 108 | QPushButton *fontColorButton; 109 | QPushButton *insertImageButton; 110 | QPushButton *saveChatInfoButton; 111 | QPushButton *clearChatInfoButton; 112 | }; 113 | 114 | #endif // CHATWIDGET_H_ 115 | -------------------------------------------------------------------------------- /include/MainWindow.h: -------------------------------------------------------------------------------- 1 | // ===================================================================================== 2 | // 3 | // Filename: MainWindow.h 4 | // 5 | // Description: 主窗口的声明 6 | // 7 | // Version: 1.0 8 | // Created: 2013年06月03日 18时09分44秒 9 | // Revision: none 10 | // Compiler: g++ 11 | // 12 | // Author: Hurley (LiuHuan), liuhuan1992@gmail.com 13 | // Company: Class 1107 of Computer Science and Technology 14 | // 15 | // ===================================================================================== 16 | 17 | #ifndef MAINWINDOW_H_ 18 | #define MAINWINDOW_H_ 19 | 20 | #include 21 | 22 | class ChatWidget; 23 | class OnlineList; 24 | class QSplitter; 25 | class QVBoxLayout; 26 | 27 | class MainWindow : public QMainWindow 28 | { 29 | Q_OBJECT 30 | public: 31 | MainWindow(); 32 | ~MainWindow(); 33 | 34 | protected: 35 | void closeEvent(QCloseEvent *event); 36 | 37 | private: 38 | void createMainWeiget(); // 创建主窗口控件 39 | 40 | private: 41 | ChatWidget *chatWidget; // 主窗口聊天控件 42 | QVBoxLayout *listLayout; // 在线用户的布局管理 43 | OnlineList *onlineList; // 在线用户列表 44 | QSplitter * mainSplitter; // 主窗口分割条 45 | }; 46 | 47 | #endif // MAIN_WINDOW_H_ 48 | -------------------------------------------------------------------------------- /include/OnlineList.h: -------------------------------------------------------------------------------- 1 | // ===================================================================================== 2 | // 3 | // Filename: OnlineList.h 4 | // 5 | // Description: 在线用户列表 6 | // 7 | // Version: 1.0 8 | // Created: 2013年06月04日 08时46分22秒 9 | // Revision: none 10 | // Compiler: g++ 11 | // 12 | // Author: Hurley (LiuHuan), liuhuan1992@gmail.com 13 | // Company: Class 1107 of Computer Science and Technology 14 | // 15 | // ===================================================================================== 16 | 17 | #ifndef ONLINELIST_H_ 18 | #define ONLINELIST_H_ 19 | 20 | #include 21 | 22 | class OnlineList : public QTableWidget 23 | { 24 | Q_OBJECT 25 | public: 26 | OnlineList(); 27 | ~OnlineList(); 28 | 29 | void createViewTitle(); 30 | void insertUserInfo(QString nickname, QString hostname, QString ipaddr); 31 | void removeUserInfo(QString hostname); 32 | }; 33 | 34 | #endif // ONLINELIST_H_ 35 | -------------------------------------------------------------------------------- /res/images/bin_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hurley25/xylchat/30a71e2448140bc563d09dae16d789901fbf2bb6/res/images/bin_empty.png -------------------------------------------------------------------------------- /res/images/fonts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hurley25/xylchat/30a71e2448140bc563d09dae16d789901fbf2bb6/res/images/fonts.png -------------------------------------------------------------------------------- /res/images/insertimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hurley25/xylchat/30a71e2448140bc563d09dae16d789901fbf2bb6/res/images/insertimage.png -------------------------------------------------------------------------------- /res/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hurley25/xylchat/30a71e2448140bc563d09dae16d789901fbf2bb6/res/images/logo.png -------------------------------------------------------------------------------- /res/images/save.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hurley25/xylchat/30a71e2448140bc563d09dae16d789901fbf2bb6/res/images/save.png -------------------------------------------------------------------------------- /res/images/textbold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hurley25/xylchat/30a71e2448140bc563d09dae16d789901fbf2bb6/res/images/textbold.png -------------------------------------------------------------------------------- /res/images/textcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hurley25/xylchat/30a71e2448140bc563d09dae16d789901fbf2bb6/res/images/textcolor.png -------------------------------------------------------------------------------- /res/images/textitalic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hurley25/xylchat/30a71e2448140bc563d09dae16d789901fbf2bb6/res/images/textitalic.png -------------------------------------------------------------------------------- /res/images/textunderline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hurley25/xylchat/30a71e2448140bc563d09dae16d789901fbf2bb6/res/images/textunderline.png -------------------------------------------------------------------------------- /res/language/qt_zh_CN.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hurley25/xylchat/30a71e2448140bc563d09dae16d789901fbf2bb6/res/language/qt_zh_CN.qm -------------------------------------------------------------------------------- /resource.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | res/images/logo.png 4 | res/images/bin_empty.png 5 | res/images/save.png 6 | res/images/textbold.png 7 | res/images/textunderline.png 8 | res/images/textcolor.png 9 | res/images/insertimage.png 10 | res/language/qt_zh_CN.qm 11 | res/images/textitalic.png 12 | res/images/fonts.png 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/ChatWidget.cpp: -------------------------------------------------------------------------------- 1 | // ===================================================================================== 2 | // 3 | // Filename: ChatWidget.cpp 4 | // 5 | // Description: 聊天显示控件 6 | // 7 | // Version: 1.0 8 | // Created: 2013年06月03日 18时41分50秒 9 | // Revision: none 10 | // Compiler: g++ 11 | // 12 | // Author: Hurley (LiuHuan), liuhuan1992@gmail.com 13 | // Company: Class 1107 of Computer Science and Technology 14 | // 15 | // ===================================================================================== 16 | 17 | #include 18 | 19 | #include "ChatWidget.h" 20 | #include "OnlineList.h" 21 | 22 | ChatWidget::ChatWidget() 23 | { 24 | createWidget(); 25 | createNetLink(); 26 | } 27 | 28 | ChatWidget::ChatWidget(OnlineList *onlineList) 29 | { 30 | this->onlineList = onlineList; 31 | createWidget(); 32 | createNetLink(); 33 | } 34 | 35 | ChatWidget::~ChatWidget() 36 | { 37 | delete sockServer; 38 | } 39 | 40 | void ChatWidget::createWidget() 41 | { 42 | chatText = new QTextBrowser(); 43 | chatText->setFocusPolicy(Qt::NoFocus); 44 | 45 | sendText = new QTextEdit(); 46 | sendText->setFocusPolicy(Qt::StrongFocus); 47 | sendText->installEventFilter(this); 48 | sendText->setMaximumHeight(sendText->sizeHint().height() >> 1); 49 | 50 | fontSizeButton = new QPushButton(QIcon(":/res/images/fonts.png"), tr("")); 51 | connect(fontSizeButton, SIGNAL(clicked()), this, SLOT(fontSize())); 52 | fontBoldButton = new QPushButton(QIcon(":/res/images/textbold.png"), tr("")); 53 | connect(fontBoldButton, SIGNAL(clicked()), this, SLOT(fontBold())); 54 | fontItalicButton = new QPushButton(QIcon(":/res/images/textitalic.png"), tr("")); 55 | connect(fontItalicButton, SIGNAL(clicked()), this, SLOT(fontItalic())); 56 | fontUnderlineButton = new QPushButton(QIcon(":/res/images/textunderline.png"), tr("")); 57 | connect(fontUnderlineButton, SIGNAL(clicked()), this, SLOT(fontUnderline())); 58 | fontColorButton = new QPushButton(QIcon(":/res/images/textcolor.png"), tr(""));; 59 | connect(fontColorButton, SIGNAL(clicked()), this, SLOT(fontColor())); 60 | insertImageButton= new QPushButton(QIcon(":/res/images/insertimage.png"), tr("")); 61 | connect(insertImageButton, SIGNAL(clicked()), this, SLOT(insertImage())); 62 | saveChatInfoButton = new QPushButton(QIcon(":/res/images/save.png"), tr("")); 63 | connect(saveChatInfoButton, SIGNAL(clicked()), this, SLOT(saveChatInfo())); 64 | clearChatInfoButton = new QPushButton(QIcon(":/res/images/bin_empty.png"), tr("")); 65 | connect(clearChatInfoButton, SIGNAL(clicked()), this, SLOT(clearChatInfo())); 66 | 67 | toolHBoxLayout = new QHBoxLayout; 68 | toolHBoxLayout->addWidget(fontSizeButton); 69 | toolHBoxLayout->addWidget(fontBoldButton); 70 | toolHBoxLayout->addWidget(fontItalicButton); 71 | toolHBoxLayout->addWidget(fontUnderlineButton); 72 | toolHBoxLayout->addWidget(fontColorButton); 73 | toolHBoxLayout->addWidget(insertImageButton); 74 | toolHBoxLayout->addWidget(saveChatInfoButton); 75 | toolHBoxLayout->addWidget(clearChatInfoButton); 76 | toolHBoxLayout->addStretch(); 77 | 78 | sendButton = new QPushButton(tr("发送(&S)")); 79 | connect(sendButton, SIGNAL(clicked()), this, SLOT(sendSlot())); 80 | 81 | buttonHBoxLayout = new QHBoxLayout(); 82 | buttonHBoxLayout->addStretch(); 83 | buttonHBoxLayout->addWidget(sendButton); 84 | 85 | mainVBoxLayout = new QVBoxLayout(); 86 | mainVBoxLayout->addWidget(chatText); 87 | mainVBoxLayout->addLayout(toolHBoxLayout); 88 | mainVBoxLayout->addWidget(sendText); 89 | mainVBoxLayout->addLayout(buttonHBoxLayout); 90 | 91 | sendText->setFocus(); 92 | setLayout(mainVBoxLayout); 93 | } 94 | 95 | void ChatWidget::createNetLink() 96 | { 97 | sockServer = new QUdpSocket(); 98 | listen_port = 9527; 99 | 100 | sockServer->bind(listen_port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); 101 | connect(sockServer, SIGNAL(readyRead()), this, SLOT(recvMessage())); 102 | sendMessage(UserLogin); 103 | } 104 | 105 | void ChatWidget::sendMessage(MessageType type, QString ipAddr) 106 | { 107 | QByteArray data; 108 | QDataStream sendData(&data, QIODevice::WriteOnly); 109 | 110 | // 消息依次是 消息类型-用户名-主机名-IP地址-(发送消息) 111 | sendData << type << getUserName() << QHostInfo::localHostName() << getIP(); 112 | 113 | switch (type) { 114 | case Message: 115 | sendData << getMessage(); 116 | break; 117 | case IamOnline: 118 | sockServer->writeDatagram(data, data.length(), QHostAddress(ipAddr), listen_port); 119 | return; 120 | // do nothing 121 | case UserLogin: 122 | case Userleft: 123 | case AskWhoOnline: 124 | break; 125 | } 126 | /* 127 | * QHostAddress::Broadcast 1 128 | * The IPv4 broadcast address. Equivalent to QHostAddress("255.255.255.255") 129 | */ 130 | sockServer->writeDatagram(data, data.length(), QHostAddress::Broadcast, listen_port); 131 | } 132 | 133 | void ChatWidget::recvMessage() 134 | { 135 | // 循环读取,读完为止 136 | while (sockServer->hasPendingDatagrams()) { 137 | QByteArray datagram; 138 | datagram.resize(sockServer->pendingDatagramSize()); 139 | sockServer->readDatagram(datagram.data(), datagram.size()); 140 | QDataStream recvData(&datagram, QIODevice::ReadOnly); 141 | 142 | int messageType; 143 | QString username, hostname, ipAddr, message; 144 | 145 | recvData >> messageType >> username >> hostname >> ipAddr; 146 | 147 | switch (messageType) { 148 | case Message: 149 | recvData >> message; 150 | addUserChatInfoOnce(username, message); 151 | break; 152 | case UserLogin: 153 | case IamOnline: 154 | disUserLogin(username, hostname, ipAddr); 155 | break; 156 | case Userleft: 157 | disUserLeft(username, hostname, ipAddr); 158 | break; 159 | case AskWhoOnline: 160 | sendMessage(IamOnline, ipAddr); 161 | break; 162 | } 163 | } 164 | } 165 | 166 | QString ChatWidget::getIP() 167 | { 168 | QList list = QNetworkInterface::allAddresses(); 169 | 170 | foreach (QHostAddress address, list) { 171 | // 只获取 IPv4 协议地址 172 | if (address.protocol() == QAbstractSocket::IPv4Protocol 173 | && address.toString() != "127.0.0.1") { 174 | return address.toString(); 175 | } 176 | } 177 | 178 | return 0; 179 | } 180 | 181 | QString ChatWidget::getUserName() 182 | { 183 | QStringList envVariables; 184 | envVariables << "USERNAME.*" << "USER.*" << "USERDOMAIN.*" << "HOSTNAME.*" << "DOMAINNAME.*"; 185 | QStringList environment = QProcess::systemEnvironment(); 186 | 187 | foreach (QString string, envVariables) { 188 | int index = environment.indexOf(QRegExp(string)); 189 | if (index != -1) { 190 | QStringList stringList = environment.at(index).split('='); 191 | if (stringList.size() == 2) { 192 | return stringList.at(1); 193 | } 194 | } 195 | } 196 | 197 | return NULL; 198 | } 199 | 200 | QString ChatWidget::getMessage() 201 | { 202 | QString msg = sendText->toHtml(); 203 | 204 | sendText->clear(); 205 | sendText->setFocus(); 206 | 207 | return msg; 208 | } 209 | 210 | void ChatWidget::addUserChatInfoOnce(QString username, QString message) 211 | { 212 | QString time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"); 213 | 214 | chatText->setTextColor(Qt::blue); 215 | chatText->setCurrentFont(QFont("Times New Roman", 12)); 216 | chatText->append(username + " " + time); 217 | chatText->append(message); 218 | chatText->verticalScrollBar()->setValue(chatText->verticalScrollBar()->maximum()); 219 | } 220 | 221 | void ChatWidget::disUserLogin(QString username, QString hostname, QString ipAddr) 222 | { 223 | chatText->setTextColor(Qt::gray); 224 | chatText->setCurrentFont(QFont("Times New Roman", 10)); 225 | chatText->append(tr("%1 [ %2 ] 加入了聊天室。").arg(username).arg(ipAddr)); 226 | onlineList->insertUserInfo(username, hostname, ipAddr); 227 | } 228 | 229 | void ChatWidget::disUserLeft(QString username, QString hostname, QString ipAddr) 230 | { 231 | chatText->setTextColor(Qt::gray); 232 | chatText->setCurrentFont(QFont("Times New Roman", 10)); 233 | chatText->append(tr("%1 [ %2 ] 离开了聊天室。").arg(username).arg(ipAddr)); 234 | onlineList->removeUserInfo(hostname); 235 | } 236 | 237 | void ChatWidget::closeEvent(QCloseEvent *) 238 | { 239 | sendMessage(Userleft); 240 | } 241 | 242 | bool ChatWidget::eventFilter(QObject *target, QEvent *event) 243 | { 244 | if (target == sendText) { 245 | if (event->type() == QEvent::KeyPress) { 246 | QKeyEvent *k = static_cast(event); 247 | if (k->key() == Qt::Key_Return || k->key() == Qt::Key_Enter) { 248 | sendSlot(); 249 | return true; 250 | } 251 | } 252 | } 253 | 254 | return QWidget::eventFilter(target, event); 255 | } 256 | 257 | void ChatWidget::fontSize() 258 | { 259 | bool isGet; 260 | QFont font = QFontDialog::getFont(&isGet, QFont("Times", 12), this); 261 | 262 | if (isGet) { 263 | sendText->setCurrentFont(font); 264 | } 265 | 266 | sendText->setFocus(); 267 | } 268 | 269 | void ChatWidget::fontBold() 270 | { 271 | static bool isBold = false; 272 | 273 | if (isBold) { 274 | sendText->setFontWeight(QFont::Normal); 275 | isBold = false; 276 | } else { 277 | sendText->setFontWeight(QFont::Bold); 278 | isBold = true; 279 | } 280 | 281 | sendText->setFocus(); 282 | } 283 | 284 | void ChatWidget::fontItalic() 285 | { 286 | static bool isItali = false; 287 | 288 | if (isItali) { 289 | sendText->setFontItalic(false); 290 | isItali = false; 291 | } else { 292 | sendText->setFontItalic(true); 293 | isItali = true; 294 | } 295 | 296 | sendText->setFocus(); 297 | } 298 | 299 | void ChatWidget::fontUnderline() 300 | { 301 | static bool isUnderline = false; 302 | 303 | if (isUnderline) { 304 | sendText->setFontUnderline(false); 305 | isUnderline = false; 306 | } else { 307 | sendText->setFontUnderline(true); 308 | isUnderline = true; 309 | } 310 | 311 | sendText->setFocus(); 312 | } 313 | 314 | void ChatWidget::fontColor() 315 | { 316 | static QColor oldColor; 317 | 318 | QColor color = QColorDialog::getColor(oldColor, this); 319 | if (color.isValid()) { 320 | sendText->setTextColor(color); 321 | oldColor = color; 322 | } 323 | 324 | sendText->setFocus(); 325 | } 326 | 327 | void ChatWidget::insertImage() 328 | { 329 | QString file = QFileDialog::getOpenFileName(this, tr("Open File"), "pic/", tr("Images (*.png *.jpg)")); 330 | QUrl fileUrl(QString("file://%1").arg(file)); 331 | QImage image = QImageReader(file).read(); 332 | QTextDocument * textDocument = sendText->document(); 333 | textDocument->addResource(QTextDocument::ImageResource,fileUrl, QVariant(image)); 334 | QTextCursor cursor = sendText->textCursor(); 335 | QTextImageFormat imageFormat; 336 | 337 | imageFormat.setWidth(image.width()); 338 | imageFormat.setHeight(image.height()); 339 | imageFormat.setName(fileUrl.toString()); 340 | cursor.insertImage(imageFormat); 341 | sendText->setFocus(); 342 | } 343 | 344 | void ChatWidget::saveChatInfo() 345 | { 346 | if (chatText->document()->isEmpty()) { 347 | QMessageBox::information(NULL, tr("友情提醒"), 348 | tr("聊天记录为空,无法保存。"), QMessageBox::Ok); 349 | } else { 350 | QString fileName = QFileDialog::getSaveFileName(this, 351 | tr("保存聊天记录"), tr("聊天记录"), tr("文本(*.txt);;All File(*.*)")); 352 | if (!fileName.isEmpty()) { 353 | QFile file(fileName); 354 | if (!file.open(QFile::WriteOnly | QFile::Text)) { 355 | QMessageBox::warning(this,tr("保存文件"), 356 | tr("无法保存文件 %1:\n %2").arg(fileName).arg(file.errorString())); 357 | } 358 | QTextStream outFile(&file); 359 | outFile << chatText->toPlainText(); 360 | } 361 | } 362 | } 363 | 364 | void ChatWidget::clearChatInfo() 365 | { 366 | chatText->clear(); 367 | } 368 | 369 | void ChatWidget::sendSlot() 370 | { 371 | if (sendText->toPlainText() == "") { 372 | QMessageBox::information(NULL, tr("友情提醒"), tr("你什么都没输入,发个毛线~~"), QMessageBox::Ok); 373 | } else { 374 | sendMessage(Message); 375 | } 376 | } 377 | 378 | -------------------------------------------------------------------------------- /src/MainWindow.cpp: -------------------------------------------------------------------------------- 1 | // ===================================================================================== 2 | // 3 | // Filename: MainWindow.cpp 4 | // 5 | // Description: 主窗口的实现 6 | // 7 | // Version: 1.0 8 | // Created: 2013年06月03日 18时09分12秒 9 | // Revision: none 10 | // Compiler: g++ 11 | // 12 | // Author: Hurley (LiuHuan), liuhuan1992@gmail.com 13 | // Company: Class 1107 of Computer Science and Technology 14 | // 15 | // ===================================================================================== 16 | 17 | #include 18 | 19 | #include "MainWindow.h" 20 | #include "ChatWidget.h" 21 | #include "OnlineList.h" 22 | 23 | MainWindow::MainWindow() 24 | { 25 | createMainWeiget(); 26 | } 27 | 28 | MainWindow::~MainWindow() 29 | { 30 | 31 | } 32 | 33 | void MainWindow::createMainWeiget() 34 | { 35 | onlineList = new OnlineList(); 36 | chatWidget = new ChatWidget(onlineList); 37 | 38 | listLayout = new QVBoxLayout(); 39 | listLayout->addWidget(onlineList); 40 | 41 | QWidget *listWidget = new QWidget(); 42 | listWidget->setLayout(listLayout); 43 | 44 | mainSplitter = new QSplitter(Qt::Horizontal); 45 | mainSplitter->addWidget(chatWidget); 46 | mainSplitter->addWidget(listWidget); 47 | 48 | setCentralWidget(mainSplitter); 49 | setWindowIcon(QIcon(":/res/images/logo.png")); 50 | resize(800, 550); 51 | setWindowTitle(tr("xylchat")); 52 | } 53 | 54 | void MainWindow::closeEvent(QCloseEvent *event) 55 | { 56 | 57 | int res = QMessageBox::question(NULL, this->windowTitle(), 58 | tr("您真的要退出本程序吗?"), QMessageBox::Yes | QMessageBox::No); 59 | if (res == QMessageBox::Yes) { 60 | event->accept(); 61 | } else{ 62 | event->ignore(); 63 | } 64 | 65 | chatWidget->sendMessage(Userleft); 66 | event->accept(); 67 | } 68 | 69 | -------------------------------------------------------------------------------- /src/OnlineList.cpp: -------------------------------------------------------------------------------- 1 | // ===================================================================================== 2 | // 3 | // Filename: OnlineList.cpp 4 | // 5 | // Description: 在线用户列表 6 | // 7 | // Version: 1.0 8 | // Created: 2013年06月04日 08时45分48秒 9 | // Revision: none 10 | // Compiler: g++ 11 | // 12 | // Author: Hurley (LiuHuan), liuhuan1992@gmail.com 13 | // Company: Class 1107 of Computer Science and Technology 14 | // 15 | // ===================================================================================== 16 | 17 | #include 18 | #include 19 | 20 | #include "OnlineList.h" 21 | 22 | OnlineList::OnlineList() 23 | { 24 | createViewTitle(); 25 | } 26 | 27 | OnlineList::~OnlineList() 28 | { 29 | 30 | } 31 | 32 | void OnlineList::createViewTitle() 33 | { 34 | // 只允许单选 35 | setSelectionMode(QAbstractItemView::SingleSelection); 36 | 37 | // 每次选中一行 38 | setSelectionBehavior(QAbstractItemView::SelectRows); 39 | 40 | // 默认不允许用户编辑数据 41 | setEditTriggers(QAbstractItemView::NoEditTriggers); 42 | 43 | // 使列完全填充并平分 44 | horizontalHeader()->setResizeMode(QHeaderView::Stretch); 45 | 46 | // 数据头左对齐 47 | horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter); 48 | 49 | // 隐藏左边垂直列号 50 | // verticalHeader()->setVisible(false); 51 | // 设置列数 52 | setColumnCount(3); 53 | 54 | // 设置不显示格子线 55 | setShowGrid(false); 56 | 57 | // 设置表头 58 | setHorizontalHeaderItem(0, new QTableWidgetItem(tr("昵称"))); 59 | setHorizontalHeaderItem(1, new QTableWidgetItem(tr("主机名"))); 60 | setHorizontalHeaderItem(2, new QTableWidgetItem(tr("IP地址"))); 61 | } 62 | 63 | void OnlineList::insertUserInfo(QString nickname, QString hostname, QString ipaddr) 64 | { 65 | bool isAdded = findItems(QHostInfo::localHostName(), Qt::MatchExactly).isEmpty(); 66 | if (isAdded) { 67 | insertRow(0); 68 | setItem(0, 0, new QTableWidgetItem(nickname)); 69 | setItem(0, 1, new QTableWidgetItem(hostname)); 70 | setItem(0, 2, new QTableWidgetItem(ipaddr)); 71 | } 72 | } 73 | 74 | void OnlineList::removeUserInfo(QString hostname) 75 | { 76 | int rowNum = findItems(hostname, Qt::MatchExactly).first()->row(); 77 | removeRow(rowNum); 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | // ===================================================================================== 2 | // 3 | // Filename: main.cpp 4 | // 5 | // Description: 主程序文件 6 | // 7 | // Version: 1.0 8 | // Created: 2013年06月03日 18时07分10秒 9 | // Revision: none 10 | // Compiler: g++ 11 | // 12 | // Author: Hurley (LiuHuan), liuhuan1992@gmail.com 13 | // Company: Class 1107 of Computer Science and Technology 14 | // 15 | // ===================================================================================== 16 | 17 | #include 18 | 19 | #include "MainWindow.h" 20 | 21 | int main(int argc, char *argv[]) 22 | { 23 | // 处理中文乱码问题 24 | QTextCodec *codec = QTextCodec::codecForName("system"); 25 | 26 | QTextCodec::setCodecForTr(codec); 27 | QTextCodec::setCodecForLocale(codec); 28 | QTextCodec::setCodecForCStrings(codec); 29 | 30 | QApplication app(argc, argv); 31 | 32 | //加载Qt自带的控件汉化文件 33 | QTranslator translator; 34 | 35 | translator.load(":/res/language/qt_zh_CN.qm"); 36 | app.installTranslator(&translator); 37 | 38 | // 使用共享内存的方法确保本程序只运行一个实例 39 | QSystemSemaphore sema("xylchat_key", 1, QSystemSemaphore::Open); 40 | sema.acquire(); 41 | 42 | QSharedMemory mem("xylchat_lock"); 43 | if (!mem.create(1)) { 44 | QMessageBox::information(0, "xylchat", "本程序只允许运行一个实例哦~亲"); 45 | sema.release(); 46 | return 0; 47 | } 48 | 49 | MainWindow *mainwindow = new MainWindow(); 50 | 51 | // 窗口显示在屏幕正中间 52 | mainwindow->move((QApplication::desktop()->width() - mainwindow->width()) >> 1, 53 | (QApplication::desktop()->height() - mainwindow->height()) >> 1); 54 | mainwindow->show(); 55 | 56 | sema.release(); 57 | 58 | return app.exec(); 59 | } 60 | 61 | -------------------------------------------------------------------------------- /xylchat.pro: -------------------------------------------------------------------------------- 1 | # ===================================================================================== 2 | # 3 | # Filename: chat.pro 4 | # 5 | # Description: 为 Linux 环境书写的 chat 项目文件 6 | # 7 | # Created: 2013年06月03日 18时05分02秒 8 | # 9 | # ===================================================================================== 10 | 11 | TEMPLATE = app 12 | TARGET = 13 | DEPENDPATH += . 14 | INCLUDEPATH += . 15 | 16 | INCLUDEPATH += include 17 | 18 | QT += network 19 | 20 | # Input 21 | HEADERS += include/MainWindow.h \ 22 | include/ChatWidget.h \ 23 | include/OnlineList.h 24 | 25 | SOURCES += src/main.cpp \ 26 | src/MainWindow.cpp \ 27 | src/ChatWidget.cpp \ 28 | src/OnlineList.cpp 29 | 30 | RESOURCES += resource.qrc 31 | --------------------------------------------------------------------------------