QT:有序排放多个按钮并处理它们的信号

    像QQ的好友列表那样排列多个按钮是一项很不错的技术,使用QToolBox可以简单地实现这个需求,而运用QT的QSignalMapper类又可以方便地处理大量由不同控件发出的信号,以下是基于这两技术的一个小例子。


思路:
1:创建多个按钮(或其他控件),并将它们放到一个group里去。
2:将按钮的clicked信号连接到signalmapper中去,并设置它们的“信号转换规则。

3:连接signalmapper的mapped信号与最终要调用的糟(ClickedButton)。


程序截图:



源代码:


#include <QtGui>
#include <QtCore>

const int NUMBER = 100;
class ButtonsBox : public QToolBox
{
	Q_OBJECT
private:
	QPushButton *button[NUMBER];
	QSignalMapper *signalMapper;
public:
	ButtonsBox(QWidget *parent = 0);
	public slots:
		void ClickedButton(const QString &text);
};

ButtonsBox::ButtonsBox(QWidget *parent /* = 0 */)
: QToolBox(parent)
{
	signalMapper = new QSignalMapper(this);
	QGroupBox *groupBox = new QGroupBox;
	QVBoxLayout *subLayout = new QVBoxLayout(groupBox);

	//处理最终信号的槽
	connect(signalMapper, SIGNAL(mapped(const QString&)), 
		this, SLOT(ClickedButton(const QString&)));

	for(int i=0; i<NUMBER; i++)
	{
		QString text = QString::number(i);
		button[i] = new QPushButton(this);
		button[i]->setText( text );
		subLayout->addWidget(button[i]);

		//原始信号传递给signalmapper
		connect(button[i], SIGNAL(clicked()), signalMapper, SLOT(map()));
		//设置signalmapper的转发规则, 转发为参数为QString类型的信号, 并把text的内容作为参数传递。
		signalMapper->setMapping(button[i], text);
	}
	addItem(groupBox, "All Buttons");
}

void ButtonsBox::ClickedButton(const QString &text)
{
	QMessageBox::information(this, "OK", text);
}

#include "main.moc"

int main(int argc, char **argv)
{
	QApplication app(argc, argv);
	ButtonsBox *toolBox = new ButtonsBox;
	toolBox->show();
	return app.exec();
}

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Qt中,信号和槽是用于对象间通信的一种机制。当一个对象发出一个信号时,与之相连的槽函数会被调用。默认情况下,在连接信号和槽时,Qt会根据对象所在的线程自动选择合适的连接方式。如果两个对象在同一线程中,Qt会使用直接连接(Qt::DirectConnection);如果在不同线程中,Qt会使用队列连接(Qt::QueuedConnection)。 Qt::DirectConnection是一种直接连接方式,它会在发出信号的线程中直接调用与之相连的槽函数。这种连接方式是最快的,因为没有信号和槽函数之间的中介过程,但是需要注意的是,如果信号和槽函数在不同的线程中,会导致线程安全问题。 使用Qt::DirectConnection连接信号和槽时,需要注意以下几点: 1. 信号和槽函数必须在同一线程中。 2. 信号和槽函数的参数类型必须一致。 3. 如果信号和槽函数都是虚函数,必须使用Qt::DirectConnection连接,否则会导致无限递归。 下面是一个使用Qt::DirectConnection连接信号和槽的例子: ```c++ // 定义一个MyObject类 class MyObject : public QObject { Q_OBJECT public: MyObject(QObject *parent = nullptr) : QObject(parent) {} signals: void mySignal(int value); public slots: void mySlot(int value) { qDebug() << "mySlot called with value: " << value; } }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); MyObject obj1; // 在主线程中创建一个对象 MyObject obj2; // 在主线程中创建另一个对象 // 使用Qt::DirectConnection连接信号和槽 QObject::connect(&obj1, &MyObject::mySignal, &obj2, &MyObject::mySlot, Qt::DirectConnection); // 在主线程中发出信号 emit obj1.mySignal(123); return a.exec(); } ``` 这段代码中,我们在主线程中创建了两个MyObject对象,然后使用Qt::DirectConnection连接了obj1的mySignal信号和obj2的mySlot槽函数。当在主线程中发出mySignal信号时,mySlot槽函数会在主线程中直接被调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值