引言

实现下面这样一个功能,点击界面的添加按钮,增加一行班级和学生的信息,刚才被点击行的按钮上的文字由添加变为删除,按钮文字为删除,点击的时候可以删除被点击行的所有控件,选中那个班级后会自动更新对应班级的学生列表,当添加的控件行太多,会自动出现垂直滚动条。

实现

下面附上完整的代码,该程序,采用了样式来设置了控件的外观,qss文件一起附上。
程序的编译环境:msvc2017 64bit,使用的QtCreate5.13.2。
程序的结构:

创建基于QDialog的项目,然后向其中添加文件,其它不多说,下面看具体实现。
main.cpp

#include "instructioneditdialog.h"#include <QApplication>
#include <QFile>int main(int argc, char *argv[])
{QApplication a(argc, argv);QFile file(":/new/prefix1/myStyle.qss");if (file.open(QIODevice::ReadOnly)) {QString strText = file.readAll();a.setStyleSheet(strText);file.close();}InstructionEditDialog w;w.show();return a.exec();
}

defineData.h

#ifndef DEFINEDATA_H
#define DEFINEDATA_H
#include <QString>typedef struct schoolSituation
{QString className;//屏幕组号QString studentsName;//场景id
}ST_SCHOOL;
typedef ST_SCHOOL stuSchoolSituation;#endif // DEFINEDATA_H

deleteaddbtn.h

#ifndef DELETEADDBTN_H
#define DELETEADDBTN_H#include <QPushButton>/*****************************功能描述:1.按钮文字为添加,发送添加命令行,2.按钮文字为删除,发送删除命令行。
*******************************/class DeleteAddBtn : public QPushButton
{Q_OBJECT
public:explicit DeleteAddBtn(int id, QWidget *parent = nullptr);~DeleteAddBtn();
protected:void mousePressEvent(QMouseEvent *event);//点击添加文字的按钮,发送添加指令信号,点击删除按钮,发送删除被点击行的控件信号void paintEvent(QPaintEvent *event);//设置样式
signals:void sigAddConstructionCtrl();//添加命令行控件void sigDelConstructionCtrl(int &id);//删除被点击行的命令行控件,id-被点击按钮的id
private:int         m_id;//按钮的id
};#endif // DELETEADDBTN_H

deleteaddbtn.cpp

#include "deleteaddbtn.h"
#include <QMouseEvent>
#include <QStyleOption>
#include <QPainter>DeleteAddBtn::DeleteAddBtn(int id,QWidget *parent)
:QPushButton(parent)
{m_id = id;setAttribute(Qt::WA_StyledBackground);//设置样式生效
}DeleteAddBtn::~DeleteAddBtn()
{}void DeleteAddBtn::mousePressEvent(QMouseEvent *event)
{if (event->button() == Qt::LeftButton) {if (text() == QStringLiteral("添加")) {setText(QStringLiteral("删除"));emit sigAddConstructionCtrl();}else if (text() == QStringLiteral("删除")) {emit sigDelConstructionCtrl(m_id);}}//    QPushButton::mousePressEvent(event);//删除所在行控件后,会继续回到此处,但是此时该类已经被析构了
}void DeleteAddBtn::paintEvent(QPaintEvent *event)
{Q_UNUSED(event);QStyleOption opt;opt.init(this);QPainter p(this);style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);QPushButton::paintEvent(event);
}

specificorderform.h

#ifndef SPECIFICORDERFORM_H
#define SPECIFICORDERFORM_H#include "defineData.h"
#include <QWidget>
#include <QMap>/*******************************功能描述:1.设置班级下拉列表为指定的列表,2.根据班级列表中选中的值,设置学生的列表,2.设置combox默认初始选中值,3.获取combox选中的值。
********************************/namespace Ui {class SpecificOrderForm;
}class SpecificOrderForm : public QWidget
{Q_OBJECTpublic:explicit SpecificOrderForm(QWidget *parent = nullptr);~SpecificOrderForm();stuSchoolSituation getOrderChoosedText();//获取指令选中的sid,sceneId
protected:void initComboBoxList();//初始化下拉列表的参数void setComboxList();//设置下拉列表
private slots:void on_classComboBox_currentTextChanged(const QString &arg1);//sid选中后,sceneid列表对应调整(sid没有变,sceneid也不变其列表)private:Ui::SpecificOrderForm *ui;QStringList                     m_studentStrList;//场景id列表QMap<QString,QStringList>       m_classStudentsMap;//sid和scenid映射表
};#endif // SPECIFICORDERFORM_H

specificorderform.cpp

#include "specificorderform.h"
#include "ui_specificorderform.h"
#include <QStyledItemDelegate>
#include <QList>SpecificOrderForm::SpecificOrderForm(QWidget *parent) :QWidget(parent),ui(new Ui::SpecificOrderForm)
{ui->setupUi(this);initComboBoxList();setComboxList();QStyledItemDelegate *delegate = new QStyledItemDelegate();//下拉项的高度起作用,似乎没有作用ui->classComboBox->setItemDelegate(delegate);ui->studentComboBox->setItemDelegate(delegate);setWindowFlags(Qt::FramelessWindowHint);setAttribute(Qt::WA_TranslucentBackground);
}SpecificOrderForm::~SpecificOrderForm()
{delete ui;
}stuSchoolSituation SpecificOrderForm::getOrderChoosedText()
{stuSchoolSituation tempClass;tempClass.className = ui->classComboBox->currentText();tempClass.studentsName = ui->studentComboBox->currentText();return tempClass;
}void SpecificOrderForm::initComboBoxList()
{QStringList students;students.append(QStringLiteral("胡姬"));students.append(QStringLiteral("张三"));students.append(QStringLiteral("李虎"));students.append(QStringLiteral("王宁"));students.append(QStringLiteral("紫荆"));students.append(QStringLiteral("梅斯卡通"));m_classStudentsMap.insert(QStringLiteral("一班"),students);students.clear();students.append(QStringLiteral("胡微姬"));students.append(QStringLiteral("张上三"));students.append(QStringLiteral("李虎上"));students.append(QStringLiteral("王宁"));students.append(QStringLiteral("紫荆史蒂夫"));students.append(QStringLiteral("梅斯卡通"));m_classStudentsMap.insert(QStringLiteral("二班"),students);students.clear();students.append(QStringLiteral("阿叔"));students.append(QStringLiteral("神盾局弟"));students.append(QStringLiteral("电视剧"));students.append(QStringLiteral("四道口"));students.append(QStringLiteral("圣诞节"));students.append(QStringLiteral("可颂"));m_classStudentsMap.insert(QStringLiteral("三班"),students);
}void SpecificOrderForm::setComboxList()
{   QStringList classStrList;QList<QString> classList = m_classStudentsMap.keys();for (int j = 0 ; j < classList.size() ; ++j) {QString strClass = classList[j];classStrList.append(strClass);}ui->classComboBox->addItems(classStrList);if (classStrList.size() != 0) {ui->classComboBox->setCurrentText(classStrList.at(0));}
}void SpecificOrderForm::on_classComboBox_currentTextChanged(const QString &arg1)
{if (m_studentStrList.size() != 0) {m_studentStrList.clear();ui->studentComboBox->clear();}QMap<QString,QStringList>::iterator it;for (it = m_classStudentsMap.begin() ; it != m_classStudentsMap.end() ;++it) {if (arg1 == it.key()) {m_studentStrList = it.value();}}ui->studentComboBox->addItems(m_studentStrList);if (m_studentStrList.size() != 0) {ui->studentComboBox->setCurrentText(m_studentStrList.at(0));}
}

instructioneditdialog.h

#ifndef INSTRUCTIONEDITDIALOG_H
#define INSTRUCTIONEDITDIALOG_H
#include "specificorderform.h"
#include "deleteaddbtn.h"
#include <QDialog>
#include <QQueue>
#include <QMap>
#include <QVBoxLayout>/*****************************功能描述:1.添加命令行控件,2.删除命令行,3.获取编辑的按钮名字和选中的命令集,4.记录并更新创建的指令行控件的id,5.调整命令行控件的布局,“太多”增加滚动条,6.设置按钮的样式。
*******************************/
typedef struct cmdCtrl
{SpecificOrderForm *order;//指令DeleteAddBtn      *btn;//指令后的按钮
}ST_CMDCTRL;
typedef ST_CMDCTRL stuCmdCtrl;namespace Ui {class InstructionEditDialog;
}class InstructionEditDialog : public QDialog
{Q_OBJECTpublic:explicit InstructionEditDialog(QWidget *parent = nullptr);~InstructionEditDialog();protected:void setVBlayout();//设置滚动区域的垂直布局void createCommandLine();//创建命令行void adjustLayoutHeight(int num);//调整布局的高度void setPushBtnStyle(DeleteAddBtn *delBtn);//设置添加/删除按钮的样式
private slots:void on_confirmBtn_clicked();//获取名称和被添加的指令void on_cancelBtn_clicked();//清空行编辑器,窗口关闭void onDelConstructionCtrl(int &id);//删除对应id的命令行控件
signals:void sigNameInstructionSet(QString &name,QList<stuSchoolSituation> &cmdSet);//发送按钮名称,sid和sceneid的指令集
private:Ui::InstructionEditDialog *ui;SpecificOrderForm           *m_orderForm;//命令行控件DeleteAddBtn                *m_pushBtn;//删除添加按钮QQueue<int>                 m_deletedId;//保存删除的指令行id,当其中不为空,创建指令行从队列中取id,直到为空重新从上一次的id增加int                         m_lastId;//保存上一次的idint                         m_id;//创建指令行的id,也为按钮idint                         m_count;//记录当前的指令行数目const int                   m_vSpacing;//控件间垂直间距bool                        m_isRecount;//指令行按钮的id是否重新计数QVBoxLayout                 *m_vLayout;//滚动区域的垂直布局QMap<int,stuCmdCtrl>        m_orderMap;//保存指令控件,键-id,值-id对应的指令和按钮
};
#endif // INSTRUCTIONEDITDIALOG_H

instructioneditdialog.cpp

#include "instructioneditdialog.h"
#include "ui_instructioneditdialog.h"InstructionEditDialog::InstructionEditDialog(QWidget *parent) :QDialog(parent),m_vSpacing(5),ui(new Ui::InstructionEditDialog)
{ui->setupUi(this);m_id = 0;m_count = 0;m_lastId = 0;m_isRecount = false;setVBlayout();createCommandLine();setWindowFlag(Qt::FramelessWindowHint);setAttribute(Qt::WA_TranslucentBackground);
}InstructionEditDialog::~InstructionEditDialog()
{delete ui;
}void InstructionEditDialog::setVBlayout()
{QWidget *widget = ui->scrollAreaWidgetContents;m_vLayout = new QVBoxLayout(widget);m_vLayout->setSpacing(m_vSpacing);m_vLayout->setContentsMargins(5,5,5,5);
}void InstructionEditDialog::adjustLayoutHeight(int num)
{int height = num * 30 + (num + 1) * m_vSpacing;//30为每行控件的高度ui->scrollAreaWidgetContents->setFixedHeight(height);
}void InstructionEditDialog::setPushBtnStyle(DeleteAddBtn *delBtn)
{QString strStyle;strStyle = "DeleteAddBtn{background-color:#040f60;color:#FFFFFF;""font-size: 18px;font-family: Microsoft YaHei;}""DeleteAddBtn:pressed{background-color:#071fbd;}";delBtn->setStyleSheet(strStyle);
}void InstructionEditDialog::createCommandLine()
{++m_count;if (m_deletedId.size() != 0) {m_id = m_deletedId.front();//first()m_deletedId.removeFirst();if (m_deletedId.count() == 0) {m_isRecount = true;}}else {if (m_isRecount) {m_id = m_lastId;}++m_id;m_lastId = m_id;}m_orderForm = new SpecificOrderForm(ui->scrollAreaWidgetContents);m_pushBtn = new DeleteAddBtn(m_id,ui->scrollAreaWidgetContents);m_pushBtn->setText(QStringLiteral("添加"));setPushBtnStyle(m_pushBtn);connect(m_pushBtn,&DeleteAddBtn::sigAddConstructionCtrl,this,&InstructionEditDialog::createCommandLine);connect(m_pushBtn,&DeleteAddBtn::sigDelConstructionCtrl,this,&InstructionEditDialog::onDelConstructionCtrl);QHBoxLayout *layout = new QHBoxLayout;layout->addWidget(m_orderForm);layout->addWidget(m_pushBtn);m_vLayout->addLayout(layout);adjustLayoutHeight(m_count);stuCmdCtrl tempOrder;tempOrder.order = m_orderForm;tempOrder.btn = m_pushBtn;m_orderMap.insert(m_id,tempOrder);
}void InstructionEditDialog::on_confirmBtn_clicked()
{QString strName = ui->namelineEdit->text();QList<stuSchoolSituation> sidSceneList;QMap<int,stuCmdCtrl>::iterator it;for (it = m_orderMap.begin() ; it != m_orderMap.end() ; ++it) {stuCmdCtrl tempCtrl = it.value();stuSchoolSituation tempSidMap = tempCtrl.order->getOrderChoosedText();sidSceneList.append(tempSidMap);}emit sigNameInstructionSet(strName,sidSceneList);accept();
}void InstructionEditDialog::on_cancelBtn_clicked()
{ui->namelineEdit->clear();reject();
}void InstructionEditDialog::onDelConstructionCtrl(int &id)
{if (m_deletedId.size() == 0) {m_isRecount = false;}QMap<int,stuCmdCtrl>::iterator it;for (it = m_orderMap.begin() ; it != m_orderMap.end() ; ++it) {if (id == it.key()) {m_deletedId.append(id);//删除后添加会出现id已被释放stuCmdCtrl tempCtrl;tempCtrl = it.value();delete tempCtrl.order;delete tempCtrl.btn;m_orderMap.erase(it);break;}}--m_count;adjustLayoutHeight(m_count);
}

instructioneditdialog.ui

specificorderform.ui

下面是样式文件:

/*学生情况编辑框背景*/
QWidget#SpecificOrderForm
{background-color:transparent;border:none;
}/*指令行指令标签*/
QWidget#SpecificOrderForm>QLabel#label,QLabel#label_2,QLabel#label_3
{font-size: 18px;font-family: Microsoft YaHei;font-weight: 400;color: #FFFFFF;
}/*班级和学生列表*/
QWidget#SpecificOrderForm>QComboBox#classComboBox,QComboBox#studentComboBox
{background-color: #121650;border:2px solid #0b54f0;font-size: 14px;font-family: Microsoft YaHei;font-weight: 400;color: #FFFFFF;
}/*下拉列表框*/
QWidget#SpecificOrderForm>QComboBox QAbstractItemView
{background-color:#55557f;outline: 1px solid #ffaa7f;   /*选定项的虚框*/selection-background-color:#121650;color:#FFFFFF;
}/*下拉列表想的高度*/
QWidget#SpecificOrderForm>QComboBox QAbstractItemView::item
{height: 20px;
}/*选中项*/
QWidget#SpecificOrderForm>QComboBox QAbstractItemView::item:selected
{background-color:#3c3cb6;
}/*指令编辑框*/
QDialog#InstructionEditDialog>QWidget#widget
{background-color:#062977;border:2px solid #0b54f0;
}/*按钮名称标签*/
QWidget#widget>QLabel#label
{font-size: 18px;font-family: Microsoft YaHei;font-weight: 400;color: #FFFFFF;
}/*按钮名称*/
QWidget#widget>QLineEdit#namelineEdit
{background-color:transparent;border-radius:2px;border:2px solid #0b54f0;font-size: 16px;font-family: Microsoft YaHei;font-weight: 400;color: #FFFFFF;
}/*滚动区域*/
QWidget#widget>QScrollArea#scrollArea
{border:none;background-color:transparent;
}/*滚动区域的垂直滚动条的主体,滑道*/
QWidget#widget>QScrollArea#scrollArea QScrollBar:vertical
{width: 10px;/*滚动条宽度*/background-color: transparent;border-radius: 5px;margin:0px,0px,0px,0px;padding-top:0px;/*上、下箭头预留位置*/padding-bottom:0px;  border:none;
}/*上箭头背景*/
QWidget#widget>QScrollArea#scrollArea QScrollBar::add-line:vertical
{background-color:transparent;
}/*下箭头背景*/
QWidget#widget>QScrollArea#scrollArea QScrollBar::sub-line:vertical
{background-color:transparent;
}/*滑块下拉后,滑块上面的背景*/
QWidget#widget>QScrollArea#scrollArea QScrollBar::add-page:vertical
{background-color:transparent;
}/*滑块上拉后,滑块下面的背景*/
QWidget#widget>QScrollArea#scrollArea QScrollBar::sub-page:vertical
{background-color:transparent;
}/*滚动区域的滚动条的滑块*/
QWidget#widget>QScrollArea#scrollArea QScrollBar::handle:vertical
{background-color: #5FC6DD;opacity: 0.5;border-radius: 5px;width:10px;min-height:20;
}/*鼠标滑过滚动条*/
QWidget#widget>QScrollArea#scrollArea QScrollBar::handle:vertical:hover
{background-color: #00FBFF;opacity: 0.5;border-radius: 5px;
}/*滚动区域窗口*/
QScrollArea#scrollArea QWidget#scrollAreaWidgetContents
{background-color:transparent;border:none;
}/*确定,取消按钮*/
QWidget#widget>QPushButton
{background-color:transparent;border: 1px solid #FFFFFF;border-radius: 6px;font-size: 14px;font-family: Microsoft YaHei;font-weight: 400;color: #FFFFFF;
}/*点击确定,取消按钮*/
QWidget#widget>QPushButton:pressed
{background-color: #00FBFF;opacity: 0.9;border-radius: 6px;font-size: 14px;font-family: Microsoft YaHei;font-weight: 400;color: #000337;
}

以上便是完整的代码。其中需要记录一下便是,当按钮被点击后,发送删除信号,来删除包含滋生在内的控件,因为是在鼠标点击事件中发送的删除控件信号,槽函数接收到信号删除控件之后,其中包含发送删除信号的按钮,然后继续返回到被删按钮的鼠标点击事件中,继续往下执行代码,这里将QPushButton::mousePressEvent(event);这句注释掉,因为按钮此时已被释放了,执行这句后程序会崩溃。当然这里这么解释可能不是很准确,但是确实和发送删除信号的按钮已经被删除有关。

qt点击按钮本身,来删除自身相关推荐

  1. qt 点击按钮不抬起,按钮无法点击

    初学qt,点击一下按钮,按钮没有抬起 再点一下才会抬起 需要取消勾选  checkable 才可以. 按钮不可点击: 1.enabled 选中时按钮才可以点击,否则是灰色的 2.我在使用 addWid ...

  2. QT实现点击按钮,切换按钮图片

    对于实现QT中点击按钮切换按钮图片的功能,之前学习时做过一个项目,用到过这个功能. 之前是用代码的方式实现,后来实习之后,参与的一个项目中也用到这个功能,所以借此机会学习了一种新方法. 新方法不用代码 ...

  3. pyqt5+qt desiger实例教程(1)创建含有三个按钮的窗口,点击按钮2输出消息、按钮3可退出

    pyqt5+qt desiger实例教程(1)创建含有三个按钮的窗口,点击按钮三可退出 目标:设计一个含有三个按钮的窗口,点击按钮2弹出消息,点击按钮3退出 如果是使用的anacoda那么自带qtde ...

  4. 最新QT从入门到实战完整版(08.qt中的坐标系-09 信号和槽-点击按钮关闭窗口_)

    最新QT从入门到实战完整版(08.qt中的坐标系-09 信号和槽-点击按钮关闭窗口_) 一.08.qt中的坐标系 二,09 信号和槽-点击按钮关闭窗口_ 来自 一.08.qt中的坐标系 二,09 信号 ...

  5. Qt 点击ToolButton按钮弹出新的窗口

    目录 第一步:新建QT设计师界面类 第二步:将新窗口的头文件加入到主窗口头文件中 第三步:为按钮事件设置信号与槽 需求说明:主窗口为mainWindow,主窗口上有一个按钮,通过点击按钮能弹出一个新的 ...

  6. [QT]实现点击按钮弹出图片的效果

    点击按钮弹出图片的实现 void MainWindow::btnTest() {QLabel* labelImage = new QLabel(this, Qt::Dialog |Qt::Window ...

  7. Qt自动填写表单并点击按钮,包括调用js方法

    本篇博客参阅了很多其他大牛的文章,具体找不到了,还望包涵>_< 因为其他博客大都是只有主要代码,对于像我这种菜鸟,根本摸不着头脑,以此想总结一下,帮助新手尽快实现功能... 主要是调用了C ...

  8. 【Python】tkinter点击按钮后获取按钮本身

    如题所示 from tkinter import *root = Tk()def b1cmd():print(b1.__dict__)b1 = Button(root,text = 'b1',) co ...

  9. qt 关闭窗口的槽函数_QT-信号槽(点击按钮关闭窗口)

    # QT-信号槽(点击按钮关闭窗口) ​ 其实也就是mfc下的响应是一个意思 信号发送者 发送信号 信号接收者 处理信号 就是这样一个流程 那么信号发送者可以是很多的情况这里举例分析一个情况: 点击按 ...

最新文章

  1. 关于第十五届全国大学生智能车竞赛 STC 单片机
  2. spring bean作用域_Srping中Bean的三种装配方式:大魏Java记10
  3. Comcast在美国境内遭遇大面积宕机和连接中断问题
  4. win7蓝屏_win7电脑蓝屏怎么办
  5. Linux系统【一】CPU+MMU+fork函数创建进程
  6. SpringBoot 动态创建多定时任务
  7. SQL2008数据类型
  8. matlab中未定义与 ‘cell‘ 类型的输入参数相对应的运算符 ‘+‘ 的解决方案
  9. 走火入魔的 C/C++ 如何通过编译器预定义的宏值来区分 target OS 是 Windows 还是 Linux...
  10. 终于找全啦!一二线城市知名互联网公司名单!对着找就对了...
  11. 《Spring揭秘》
  12. lammps教程:叠加力场hybrid/overlay设置方法介绍
  13. mysql替换后的zzigu_MySQL导入数据报错Got a packet bigger than‘max_allowed_packet’bytes错误的解决方法...
  14. 补充记录vue3中rrweb-player组件实现网页录屏的一个BUG解决
  15. 【LaTeX】子图和图片并排
  16. xml开发笔记(一):tinyXml2库介绍、编译和工程模板
  17. initrd和initramfs的区别
  18. 【原生Ajax】全面了解xhr的概念与使用。
  19. javapoet动态生成java代码
  20. 谷歌逐梦穿戴圈:Wear OS的失败能够靠Pixel Watch挽回吗?

热门文章

  1. 岗岭集团打造中国最大的线上线下一体化的医药健康平台
  2. DLA实现跨地域、跨实例的多AnalyticDB读写访问 1
  3. Andrew Ng教你如何引领公司进入AI时代
  4. 赠书 | 读懂 x86 架构 CPU 虚拟化,看这文就够了
  5. 华为豪投20亿!3年培养100万AI人才,网友不服!
  6. “12306”的架构到底有多6?
  7. BDTC 2019 | 七个开发者能干多大的事?​
  8. OpenStack精华问答 | OpenStack服务介绍
  9. css让背景图片显示透明遮罩_CSS项目测试(支持深色模式)
  10. java 反编译class文件_用Java实现JVM第三章《解析class文件》