-2

This is probably something simple I need to do, I'm trying too access the ui from more than 1 class it works in the mainwindow class but not in the Socket class. I want to write to the display of the ui from the socket class but when I type ui. it should automatically create ui-> and give me a bunch of options. Here is mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QProcess>
#include "studentlist.h"
#include "student.h"

namespace Ui {
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    Ui::MainWindow *ui;

private slots:
    void on_buttonGraduate_clicked();
    void on_buttonAverage_clicked();
    void on_buttonDisplay_clicked();
    void on_buttonAddModule_clicked();
    void acceptNewStudent();
    void processFinished(int);

protected:

private:

    QProcess* process;
    StudentList* studentList;

    void displayDetail(QString msg, AbstractStudent* asp);
    int doCheck();
    void closeEvent(QCloseEvent *);
};

#endif // MAINWINDOW_H

and socket.h

#ifndef SOCKET_H
#define SOCKET_H

#include <QObject>
#include <QDebug>
#include <QTcpSocket>
#include <QAbstractSocket>
#include <QMainWindow>
#include "mainwindow.h"
#include "ui_mainwindow.h"


class Socket : public QObject
{
    Q_OBJECT
public:
    explicit Socket(QObject *parent = 0);
    void run();
signals:

public slots:
    void connected();
    void disconnected();
    void bytesWritten(qint64 bytes);
    void readyRead();
private:
    QTcpSocket *socket;

};

#endif // SOCKET_H

Adding .cpp files

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QProcess>
#include <QMessageBox>
#include <QFile>
#include "studentserializer.h"
#include <QTextStream>
#include <QCloseEvent>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    process = 0;
    studentList = StudentList::getInstance();

}

MainWindow::~MainWindow()
{
    delete process;
    delete ui;
}


void MainWindow::on_buttonAddModule_clicked()
{
    process = new QProcess(this);
    process->start("C:/Unisa/COS3711/Solutions to assignment 2/S2A2Q4ProcessStudent-build-desktop/debug/S2A2Q1GetStudent.exe");
    connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(acceptNewStudent()));
    connect(process, SIGNAL(finished(int)), this, SLOT(processFinished(int)));
}

void MainWindow::acceptNewStudent()
{
    QByteArray bytes = process->readAllStandardOutput();
    QStringList items = QString(bytes).split("#");

    QString number = items.at(0);
    QString module = items.at(1);
    int mark = items.at(2).toInt();

    //check if student already exists
    int index = studentList->exists(number);
    if (index == -1) // student does not yet exist
    {
        Student* student = new Student;
        student->setNumber(number);
        student->addModule(module, mark);
        studentList->addStudent(student);

        displayDetail("New student added", student);
    }
    else // student does exist
    {
        AbstractStudent* a = studentList->getStudent(index);
        a->addModule(module, mark);
        displayDetail("Updated student", a);
        a = 0;
    }
}

void MainWindow::on_buttonDisplay_clicked()
{
    int index = doCheck();
    if (index >=0)
    {
        AbstractStudent* asp = studentList->getStudent(index);
        displayDetail("Displaying student", asp);
        asp = 0;
    }
}

void MainWindow::displayDetail(QString msg, AbstractStudent* asp)
{
    ui->display->clear();
    ui->display->append(msg);
    ui->display->append("Number: " + asp->getNumber());
    QMap<QString, int> mods = asp->getModules();
    QMapIterator<QString, int> i(mods);
    while (i.hasNext())
    {
        i.next();
        ui->display->append("Module: " + i.key() + " Mark: " + QString::number(i.value()));
    }
}

void MainWindow::on_buttonAverage_clicked()
{
    int index = doCheck();
    if (index>=0)
    {
        AbstractStudent* asp = studentList->getStudent(index);
        displayDetail("Displaying student", asp);
        ui->display->append("Module average: " + QString::number(asp->average()));
        asp = 0;
    }
}

void MainWindow::on_buttonGraduate_clicked()
{
    int index = doCheck();
    if (index>=0)
    {
        AbstractStudent* asp = studentList->getStudent(index);
        QString msg = asp->graduate()?"This student graduates":"This student does not graduate";
        displayDetail(msg, asp);
        asp = 0;
    }
}

int MainWindow::doCheck()
{
    QMessageBox warning;
    warning.setIcon(QMessageBox::Critical);
    int index=-1;

    if (ui->studentNumber->text().size() == 0)
    {
        warning.setText("Provide a number");
        warning.exec();
        index = -1;
    }
    else
    {
        index = studentList->exists(ui->studentNumber->text());

        if (index == -1)
        {
            warning.setText("Number does not exist");
            warning.exec();
        }
    }
    ui->studentNumber->clear();
    ui->studentNumber->setFocus();
    ui->display->clear();
    return index;
}

void MainWindow::closeEvent(QCloseEvent* event)
{
    QFile studentFile("studentlist.xml");
    studentFile.open(QIODevice::WriteOnly);
    QTextStream toFile(&studentFile);

    StudentSerializer s;
    QList<AbstractStudent*>* list = studentList->returnList();
    for (int i=0; i<list->size(); i++)
        s.addStudent(list->at(i));
    QDomDocument tempDoc = s.getDoc();
    toFile << tempDoc.toString();
    studentFile.close();

    event->accept();
}

void MainWindow::processFinished(int)
{
    process->close();
    process->deleteLater();
    process=0;
}

And socket.cpp

#include "socket.h"

Socket::Socket(QObject *parent) :
    QObject(parent)
{
}

void Socket::run(){
    socket = new QTcpSocket(this);

    connect(socket,SIGNAL(connected()),this,SLOT(connected()));
    connect(socket,SIGNAL(disconnected()),this,SLOT(disconnected()));
    connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()));
    connect(socket,SIGNAL(bytesWritten(qint64)),this,SLOT(bytesWritten(qint64)));

    qDebug() << "Connecting...";

    socket->connectToHost("twitter.com",80);
    if (!socket->waitForConnected(3000))
    {

         qDebug() << "error:" << socket->errorString();
    }
}

void Socket::connected(){
    qDebug() << "Connected";

}

void Socket::disconnected(){
    qDebug() << "Disconected";
}

void Socket::bytesWritten(qint64 bytes){
    qDebug() << "we wrote: " << bytes;
}

void Socket::readyRead(){
    qDebug() << "Reading...";
    socket->readAll();
}

those qDebug's I would like to write to the QTextEdit called display

4

2 回答 2

3

Qt 有信号槽机制来做这些事情!

您永远不能从工作人员访问 GUI。

在 中创建一个信号,Socket并在QMainWindow. 然后您可以将一些QString's 发送到 GUI。

主窗口.h:

public slots:
  void showMessage( const QString& message );

private:
  QLabel* label_; // or something similar

主窗口.cpp:

void MainWindow::showMessage( const QString& message )
{
  // dont forget to create label_ within the ctor
  this->label_->setText(message) // or something similar
}

套接字.h:

signals:
  void sendMessage( const QString& message ) const;

套接字.cpp:

// add or replace the qDebug() part with
emit this->sendMessage("DEBUG MESSAGE");

此外,连接MainWindowSocket分类:

QObject::connect(sender*, &Socket::sendMessage, receiver*, &MainWindow::showMessage);
// or Qt 4 style
// QObject::connect(sender*, SIGNAL(sendMessage(QString), receiver*, SLOT(showMessage(QString));
于 2013-10-02T10:56:38.110 回答
2

您的套接字类是否在不同的线程中运行?如果是这样,则不允许您直接访问 ui。如果不是,您必须给套接字类一个指向 ui 的指针,但我不建议这样做。

首选的解决方案是在套接字类中创建一个信号并将其连接到主窗口类中的插槽。在这个插槽中做你想要的用户界面工作。在套接字类中,只在给定时间发出信号,信号可以保存发送到插槽的数据对象。

于 2013-10-02T10:43:21.763 回答