qt点击按钮本身,来删除自身
引言
實現下面這樣一個功能,點擊界面的添加按鈕,增加一行班級和學生的信息,剛才被點擊行的按鈕上的文字由添加變為刪除,按鈕文字為刪除,點擊的時候可以刪除被點擊行的所有控件,選中那個班級后會自動更新對應班級的學生列表,當添加的控件行太多,會自動出現垂直滾動條。
實現
下面附上完整的代碼,該程序,采用了樣式來設置了控件的外觀,qss文件一起附上。
程序的編譯環境:msvc2017 64bit,使用的QtCreate5.13.2。
程序的結構:
創建基于QDialog的項目,然后向其中添加文件,其它不多說,下面看具體實現。
main.cpp
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_Hdeleteaddbtn.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_Hdeleteaddbtn.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_Hspecificorderform.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_Hinstructioneditdialog.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
下面是樣式文件:
以上便是完整的代碼。其中需要記錄一下便是,當按鈕被點擊后,發送刪除信號,來刪除包含滋生在內的控件,因為是在鼠標點擊事件中發送的刪除控件信號,槽函數接收到信號刪除控件之后,其中包含發送刪除信號的按鈕,然后繼續返回到被刪按鈕的鼠標點擊事件中,繼續往下執行代碼,這里將QPushButton::mousePressEvent(event);這句注釋掉,因為按鈕此時已被釋放了,執行這句后程序會崩潰。當然這里這么解釋可能不是很準確,但是確實和發送刪除信號的按鈕已經被刪除有關。
總結
以上是生活随笔為你收集整理的qt点击按钮本身,来删除自身的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 银河麒麟通过命令行安装软件没有安装上
- 下一篇: qt在加入Q_OBJECT宏之后出现编译