目录
实现一个如图所示的交互式执行cmd命令的小案例,仅仅实现基本的读写功能,还有很多不完善的地方。
1、布局,设置一些控件属性
void MainWindow::initCommandExecute()
{
// 设置textEdit(大的编辑框)为只读,这里只用于显示
ui->textEdit->setReadOnly(true);
// lineEdit(小的编辑框)获取焦点,程序一运行便可以直接输入
ui->lineEdit->setFocus();
// 给”发送“按钮添加快捷键,按下回车键等于点击了按钮
ui->pushButton_send->setShortcut(QKeySequence(QLatin1String("Return")));
}
2、启动cmd进程
QT提供了QProcess类,用于启动外部程序并与他们进行通信,使用start方法启动cmd进程。
setProcessChannelMode(QProcess::MergedChannels) 作用是:QProcess将运行进程的输出合并到标准输出通道(stdout)中。标准错误通道(stderr)将不会接收任何数据。运行过程的标准输出和标准错误数据是交错的(QT文档中给的解释)。这里如果不加这句,在启动的cmd进程中,输入没有或错误的shell命令,会得不到提示结果,没有类似于“ 'ip' 不是内部或外部命令,也不是可运行的程序或批处理文件。”这样的提示。
void MainWindow::startProcess()
{
this->process = new QProcess(this);
this->process->setProcessChannelMode(QProcess::MergedChannels);
this->process->start("cmd.exe");
}
3、给“发送”按钮添加点击事件,把命令输入到cmd进程
// 连接点击信号和槽函数
connect(ui->pushButton_send,SIGNAL(clicked()),this,SLOT(sendCommand()));
"\r\n"表示回车换行。在获取的command字符串中,末尾没有回车换行符,直接输入到cmd进程中命令不会执行,cmd没收到回车换行,以为命令没结束。
void MainWindow::sendCommand()
{
// 获取到lineEdit编辑框中的文本,并在末尾拼接上“\r\n”
QString command = ui->lineEdit->text()+"\r\n";
// 清空lineEdit编辑框的内容
ui->lineEdit->clear();
// 获取焦点,用鼠标点击“发送”按钮后可以自动获取焦点
ui->lineEdit->setFocus();
// 把command命令通过write()输入到cmd进程中
QByteArray commandByte = command.toLatin1();
this->process->write(commandByte);
}
4、获取cmd进程的输出内容
// 绑定标准输出通道信号和槽函数
connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(readProcess()));
append() 和 insertPlainText()的区别:append是追加到内容末尾的下一行,也就是在末尾先回车换行再追加;insertPlainText是直接在末尾追加。
void MainWindow::readProcess()
{
// 读取输出通道中的全部内容
QByteArray resultByte = process->readAll();
QString result = QString::fromLocal8Bit(resultByte);
// 追加到textEdit编辑框中
ui->textEdit->insertPlainText(result);
// 更新textEdit内容,在这个案例中不加也可以
ui->textEdit->update();
// 设置光标位置为内容的最后
ui->textEdit->moveCursor(QTextCursor::End);
}
5、补充stackedWidget控件如何切换页面
// 命令控制按钮
connect(ui->pushButton_command,&QPushButton::clicked,[=]{
ui->stackedWidget->setCurrentIndex(0);
});
// 目录结构按钮
connect(ui->pushButton_directory,&QPushButton::clicked,[=]{
ui->stackedWidget->setCurrentIndex(1);
});