经过了一个小程序的练手,应该写点实用的东西了。学校里上网需要使用drcom客户端进行登录。虽然sourceforge有一个linux的drcom客户端的开源项目,但是这是一个基于命令行的程序,开始用起来不是很方便。
对drcom-1.4.7的分析:
      drcom分为drcomc,drcomd和一个内核模块。没有看过linux内核的编程,内核模块直接略过。drcomd是这个程序的守护程序,负责接收drcomc发送过去的指令,并向服务器提交相应的指令。drcomc是客户端程序,通过命令行参数,向drcomc发送登录、注销和修改密码的指令。两者之间通过UNIX的进程间内部socket进行通信。
      最早写drcom的GUI是针对drcom-1.3.7的,那时候自己电脑的内核还是2.6.22的,于是就根据那个版本的drcom写了一个实现drcomc功能的GUI。现在针对drcom-1.4.7的GUI,也仅仅实现了drcomc的功能,所以还不是很方便。但是相比较前面的版本,稍微多加了一点人性化的功能。
      首先,加入了修改drcom.conf文件的功能,能够方便的在一个对话框中可视化的修改配置内容。因为drcom-1.4.7中,多加了一个device的选项,以前的mac选项都变成可选的了,但是对于自己修改过mac地址的人来说,mac选项还是必要的,否则drcomd将会使用从设备中读取到的mac地址来连接服务器。因此,通过Qt4的QNetworkInterface类,得到电脑上每一个网络设备的mac地址。
相关代码:foreach(QNetworkInterface interface, QNetworkInterface::allInterfaces())
             {
                    NIC->addItem(interface.name());
              }
使用QNetworkInterface的静态函数allInterfaces(),取得电脑上所有的网络设备(包括本地回路)。然后使用Qt的foreach宏,遍历整个列表,将每个设备名添加到NIC中(一个comboBox的对象)。
    interface = QNetworkInterface::interfaceFromName(interfaceName);
    if(interface.isValid())
    {
        localMAC->setText(tr("MAC地址:") +  interface.hardwareAddress());
    }
每次下拉框(comboBox)被改动之后,调用该函数,判断网络接口名是否正确,并读取该网络接口名的mac地址(hardwareAddress)。
 

用Qt <wbr>4.4编写drcom的GUI
配置的设置窗口&#xff08;没有使用root权限&#xff0c;无法读取/etc/drcom.conf文件&#xff09;
 

由于学校的网费充值是通过专门的充值网页进行的&#xff0c;为了方便充值&#xff08;也借鉴了windows版的drcom&#xff09;&#xff0c;在菜单栏中增加了充值网页这个按钮&#xff08;Action&#xff09;。
      Qt4.4新增加了对webkit的支持&#xff0c;这使得显示网页变得非常容易&#xff1a;
首先加载显示网页所需的头文件&#xff1a;#include
然后声明一个QWebView的指针&#xff0c;然后加载&#xff08;QWebView::load()&#xff09;需要打开的地址&#xff0c;最后调用显示函数(QWebView::show())&#xff1a;
    QWebView *view &#61; new QWebView(0);
    view->load(QUrl("http://xx.xx.xx/"));
    view->show();
      这里只是简单的显示网页&#xff0c;没有实现一些浏览器的基本功能&#xff08;比如自动完成表单&#xff09;&#xff0c;因此只需要简单使用QWebView类就可以了&#xff0c;不需要使用其他webkit的类。相关的类还有&#xff1a; QWebFrame(用于控制网页的框架)&#xff0c;QWebHistory(操作网页的历史)&#xff0c;QWebPage(网页相关)等。
      不过&#xff0c;需要注意的是&#xff0c;Qt默认不会加载QtWebkit的链接库&#xff0c;如果需要使用该链接库&#xff0c;需要在.pro文件中添加QT &#43;&#61; webkit &#xff0c;这样才能让qmake在生成Makefile文件的时候&#xff0c;加入对webkit链接库的连接。
 

用Qt <wbr>4.4编写drcom的GUI&#xff08;续&#xff09;
使用QtWebkit加载的充值网页
 

上次的显示网页模块感觉做的不是很人性话&#xff0c;明明可以直接从本地得到用户名和密码&#xff0c;但是却没有能够好好利用这些内容&#xff0c;让用户多输入了这些信息。
      为了实现自动填充网页中的表单&#xff0c;找了很长时间。刚开始&#xff0c;没有什么概念&#xff0c;就利用刚刚学到的html知识&#xff0c;直接从QWebView->QWebFrame->QWebFrame&#xff0c;然后从webFrame中提取网页表单中的相关元素&#xff0c;修改网页的源代码之后重新显示。
QString html &#61; parentFrame->toHtml();    //得到html源代码
int pos &#61; html.indexOf("\"name\"");         //搜索代码中的"name"字符串&#xff08;包含引号&#xff09;
pos &#61; html.indexOf(">",pos);                  //搜索该输入框的结尾
html.insert(pos," value&#61;&#39;xxx&#39; ");              //添加value的值
parentFrame->setHtml(html,parentFrame->url());//使用新的html显示&#xff0c;并指定根路径为原URL
      这样的方法是可以实现在表单中预填充字符的&#xff0c;但是由于重新调用了setHtml()函数重新加载网页&#xff0c;重新加载完毕后&#xff0c;webView还是会发射loadFinished(bool)信号的。因此&#xff0c;在这个函数中&#xff0c;需要使用一个标记来确定是否是第二次加载网页。&#xff08;为了提取html&#xff0c;必须将loadFinished(bool)信号连接到自定义的槽&#xff0c;否则在未加载完网页之前调用toHtml()不能得到网页的html代码&#xff09;。
      在网上搜索了关于webkit处理Javascript之后&#xff0c;了解到QWebFrame中还有一个evaluateJavascript()函数&#xff0c;该函数的参数是QString&#xff0c;会将传入的字符串当作Javascript代码进行解析。因此&#xff0c;可以对网页的frame使用该函数&#xff0c;添加Javascript代码&#xff0c;就能很轻松的操作表单了。
parentFrame->evaluateJavascript("document.LOGIN.name.value&#61;&#39;xxx&#39;");
view->show();
使用这个函数非常方便&#xff0c;不需要写脚本的标记符&#xff0c;也不用加上“&#xff1b;”&#xff08;正因为这样&#xff0c;好像不能执行多条Javascript语句&#xff09;。
      终于又为那个程序多加了一个功能&#xff0c;现在只差控制守护进程的功能了。
 

用Qt <wbr>4.4编写drcom的GUI&#xff08;再续&#xff09;