关于QWidgetList中item的赋值问题

是这样的,个人在Qt中时常因为item的赋值问题而苦恼,所以就写了这篇文章来作为一个备份,如果外来者观看的话建议通过目录索引到关键内容以提高查阅效率

案例1 文章列表的展现以及点击后的详细页面

前提

首先,你需要一个在文章类中写一个注册宏

像这样:

Q_DECLARE_METATYPE(article)
Q_DECLARE_METATYPE(article*)

然后这是文章类的头文件:


#ifndef ARTICLE_H
#define ARTICLE_H

#include <QString>
#include <vector>
#include <QMetaType>

class article
{
public:
    article(const QString &title = "", const QString &tags = "", const QString &author = "", const QString &content = "", bool isban = false, int likes = 0)
            : title(title), tags(tags), author(author), content(content), isban(isban), likes(likes) {}


    //读取,不做出改变
    QString get_articleTitle() const;
    QString get_articleTag() const;
    QString get_articleAuthor() const;
    QString get_articleContent() const;
    bool get_articleIsban() const;
    int get_articleLikes() const;

    //设置,做出改变
    void set_articleTitle(QString title);
    void set_articleTag(QString tags);
    void set_articleAuthor(QString author);
    void set_articleContent(QString ci);
    void set_articleIsban(bool isBan);
    void set_articleLikes(int likes);



private:
    QString title;
    QString tags;
    QString author;
    QString content;
    bool isban;
    int likes;

};

// 在全局范围内注册自定义类型
Q_DECLARE_METATYPE(article)
Q_DECLARE_METATYPE(article*)
#endif // ARTICLE_H

之后,要写一个QList<article>的列表来存储文章列表

个人倾向于认为查看文章列表是用户的一个行为,所以我把这个列表写在了用户类(知道这样写效率低,但是这只是个样例)

#ifndef USER_H
#define USER_H

#include "article.h"

#include <QString>
#include <QList>

class User
{
public:
    enum role { banUser, user, admin };

    QList<article> searchArticleList; //文章类的列表
    QList<article> OriginalArticleList;

    User(QString &username, QString &password, role initialRole = user)
        : username(username), password(password), userRole(initialRole) { loadArticlesFromFile();}

    // 获取用户名
    QString get_username() const { return username; }

    // 获取密码
    QString get_password() const { return password; }

    // 获取用户角色
    role get_userRole() const { return userRole; }


    // 设置用户名
    void set_username(const QString &newUsername) { username = newUsername; }

    // 设置密码
    void set_password(const QString &newPassword) { password = newPassword; }

    // 设置用户角色
    void set_userRole(role newRole) { userRole = newRole; }


    //写文章
    void writeArticle(const QString &title,const QString &tags,const QString &author,const QString &content);

    //阅读文章
    void readArticle(const QString &title);

    //点赞文章
    void likeArticle(const QString &title);

    //从文档加载文章
    void loadArticlesFromFile();

    //三个排序
    void sortArticlesByTitle();

    void sortArticlesByLikes();

    void sortArticlesByAuthor();
private:
    QString username;
    QString password;
    role userRole;

};

#endif // USER_H

然后,就是要从文档中读取文章,然后将文章存储到文章列表中了(就是searchArticleList和OriginalArticleList)

void User::loadArticlesFromFile() {
    // 清空现有文章列表
    OriginalArticleList.clear();

    QFile file("articles.txt");
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "无法打开文件!";
        return;
    }

    QTextStream in(&file);
    QString line;

    // 遍历文件并加载所有文章
    while (!in.atEnd()) {
        line = in.readLine();

        // 假设每行的文章数据格式为: 标题|标签|内容
        QStringList parts = line.split("###"); // 使用 "###" 作为分隔符
        if (parts.size() == 6) {
            QString articleTitle = parts[0];
            QString articleTags = parts[1];
            QString articleAuthor = parts[2];
            QString articleContent = parts[3];
            bool articleIsBanned = parts[4].toInt() == 1;
            int articleLikes = parts[5].toInt();

            // 创建 article 对象
            article loadedArticle(articleTitle, articleTags, articleAuthor, articleContent, articleIsBanned, articleLikes);

            // 添加到文章列表
            OriginalArticleList.append(loadedArticle);
            searchArticleList.append(loadedArticle);

        }
    }

    file.close();
}

正文

之后,就是最关键的部分:如何将article类的list赋值到item上

首先你要申明一个QListWidget:
QListWidget *articleList = new QListWidget(this);
然后写一个for遍历前提的文章列表,在遍历中将文章列表赋值到item中,最后将item加入到上面申明的articlelist上
 for (const article& art : currentUser.searchArticleList) {
        QString title = art.get_articleTitle();
        QString tags = art.get_articleTag();
        QString textInItem = title + "\n" + tags;

        // 创建一个新的 QListWidgetItem 并将文本添加到该项
        QListWidgetItem *item = new QListWidgetItem(textInItem);

        // 将文章对象存储在列表项的 UserRole 数据中
        item->setData(Qt::UserRole, QVariant::fromValue(art));

        // 将新创建的项添加到 QListWidget
        articleList->addItem(item);
    }

对上述代码做出以下阐述:

setData()设置item的数据
Qt::UserRole用户自定义的数据类型
QVariantQVariant具有自动类型转换的功能,可以在需要时将存储的数据自动转换为目标类型
QVariant::fromValue()对于自定义类型,要使QVariant::fromValue能够工作,该类型需要被Qt的元对象系统所识别。这通常意味着该类型需要继承自QObject(如果它是一个类)并使用Q_OBJECT宏,同时可能还需要为该类型注册一个元类型(使用qRegisterMetaType函数或Q_DECLARE_METATYPE宏)(个人选择Q_DECLARE_METATYPE)

图片来自qt的assistant,5.12.12版本中的路径是qt\5.12.12\mingw73_64\bin

实现效果:

后文

如何点击显示详细内容?

个人选择是点击就切成显示详细信息的页面

切换页面:

private slots :
    void articleClicked(QListWidgetItem *item);
    
connect(articleList,&QListWidget::itemClicked,this,&guidingPage::articleClicked);
void guidingPage::articleClicked(QListWidgetItem *item) {
    if (item == nullptr) {
        qDebug() << "Item is null, skipping the click event!";
        return;  // 退出函数,避免崩溃
    }
    article selectedArticle = item->data(Qt::UserRole).value<article>();
    ArticleDetailPage *detailPage = new ArticleDetailPage(currentUser, selectedArticle);
    detailPage->show();
    this->close();

传值到另一个界面后如何显示:

ArticleDetailPage::ArticleDetailPage(User user, const article &art, QWidget *parent)
    : currentUser(user), QWidget(parent), articleDetail(art)
{

 // 创建标题标签
    QLabel *titleLabel = new QLabel(art.get_articleTitle(), this);
    titleLabel->setStyleSheet("font-size: 40px; font-weight: bold; color: #333;");

    // 创建作者标签
    QLabel *authorLabel = new QLabel("作者: " + art.get_articleAuthor(), this);
    authorLabel->setStyleSheet("font-size: 20px; color: #555;");
}

实现效果:

只用看标题和作者就行了其实

就写这么多吧


然后个人其实还是有些关于QWidgetListItem的一些小问题的,比如如何让item自己刷新,而不用跟随页面刷新而刷新,这个问题个人作为qt方面完全自学的新手还在学习中.当然,因为学校数据结构大作业的原因,qt程序需要打包上交给学校方面,但是个人对于的打包总是打包的一塌糊涂,要么就是少了拓展,要么打开就闪退(在别人电脑上会闪退,但是自己电脑运行打包好的程序是没问题的)😭
然后个人用Enigma Virtual Box封包了闪退版后甚至直接变成了这样:

(自己联系自己?)

关于这个版本问题,我同学给出的解答是:用汇编修复导入表........
罢了,今日起,猛学汇编!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值