Java实现Qt的SIGNAL-SLOT机制
SIGNAL-SLOT是Qt的一大特色,使用起来十分方便。在传统的AWT和Swing编程中,我们都是为要在
- public static void connect(QObject sender, String signal, Object receiver, String slot) {
- if (sender.signalSlotMap == null)
- sender.signalSlotMap = new HashMap<String, List<ReceiverSlot>>();
- List<ReceiverSlot> slotList = sender.signalSlotMap.get(signal);
- if (slotList == null) {
- slotList = new LinkedList<ReceiverSlot>();
- sender.signalSlotMap.put(signal, slotList);
- }
- slotList.add(createReceiverSlot(receiver, slot));
- }
- static class ReceiverSlot {
- Object receiver;
- Method slot;
- Object[] args;
- }
- private static ReceiverSlot createReceiverSlot(Object receiver, String slot) {
- ReceiverSlot receiverSlot = new ReceiverSlot();
- receiverSlot.receiver = receiver;
- Pattern pattern = Pattern.compile("(\\w+)\\(([\\w+,]*)\\)");
- Matcher matcher = pattern.matcher(slot);
- if (matcher.matches() && matcher.groupCount() == 2) {
- // 1.Connect SIGNAL to SLOT
- try {
- String methodName = matcher.group(1);
- String argStr = matcher.group(2);
- ArrayList<String> argList = new ArrayList<String>();
- pattern = Pattern.compile("\\w+");
- matcher = pattern.matcher(argStr);
- while (matcher.find())
- argList.add(matcher.group());
- String[] arguments = argList.toArray(new String[0]);
- receiverSlot.slot = findMethod(receiver, methodName, arguments);
- receiverSlot.args = new Object[0];
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
- else {
- // 2.Connect SIGNAL to SIGNAL
- if (receiver instanceof QObject) {
- receiverSlot.slot = emitMethod;
- receiverSlot.args = new Object[] { slot };
- }
- }
- return receiverSlot;
- }
- private static Method emitMethod;
- protected Map<String, List<ReceiverSlot>> signalSlotMap;
- static {
- try {
- emitMethod = QObject.class.getDeclaredMethod("emit", String.class, Object[].class);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- private static Method findMethod(Object receiver, String methodName, String[] arguments)
- throws NoSuchMethodException {
- Method slotMethod = null;
- if (arguments.length == 0)
- slotMethod = receiver.getClass().getMethod(methodName, new Class[0]);
- else {
- for (Method method : receiver.getClass().getMethods()) {
- // 1.Check method name
- if (!method.getName().equals(methodName))
- continue;
- // 2.Check parameter number
- Class<?>[] paramTypes = method.getParameterTypes();
- if (paramTypes.length != arguments.length)
- continue;
- // 3.Check parameter type
- boolean isMatch = true;
- for (int i = 0; i < paramTypes.length; i++) {
- if (!paramTypes[i].getSimpleName().equals(arguments[i])) {
- isMatch = false;
- break;
- }
- }
- if (isMatch) {
- slotMethod = method;
- break;
- }
- }
- if (slotMethod == null)
- throw new NoSuchMethodException("Cannot find method[" + methodName +
- "] with parameters: " + Arrays.toString(arguments));
- }
- return slotMethod;
- }
- protected void emit(String signal, Object... args) {
- System.out.println(getClass().getSimpleName() + " emit signal " + signal);
- if (signalSlotMap == null)
- return;
- List<ReceiverSlot> slotList = signalSlotMap.get(signal);
- if (slotList == null || slotList.isEmpty())
- return;
- for (ReceiverSlot objSlot : slotList) {
- try {
- if (objSlot.slot == emitMethod)
- objSlot.slot.invoke(objSlot.receiver, objSlot.args[0], args);
- else
- objSlot.slot.invoke(objSlot.receiver, args);
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- public class QWidget<T extends JComponent> extends QObject implements QSwing<T> {
- protected T widget;
- public QWidget(Class<T> clazz) {
- try {
- widget = clazz.newInstance();
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- }
- @Override
- public T getSwingWidget() {
- return this.widget;
- }
- }
- public class QPushButton extends QWidget<JButton> {
- public static final String CLICKED = "clicked";
- public QPushButton(String text) {
- super(JButton.class);
- widget.setText(text);
- widget.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- emit(CLICKED);
- }
- });
- }
- }
- public class QLineEdit extends QWidget<JTextField> {
- public static final String RETURN_PRESSED = "returnPressed";
- public QLineEdit() {
- super(JTextField.class);
- widget.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- emit(RETURN_PRESSED);
- }
- });
- }
- }
- public class AddressBar extends QWidget<JPanel> {
- /**
- * SIGNAL
- */
- public static final String NEW_BUTTON_CLICKED = "newButtonClicked";
- public static final String GO_TO_ADDRESS = "goToAddress(String,String)";
- /**
- * SLOT
- */
- public static final String HANDLE_GO_TO_ADDRESS = "handleGoToAddress()";
- private QPushButton newButton;
- private QLineEdit addressEdit;
- private QPushButton goButton;
- public AddressBar() {
- super(JPanel.class);
- // 1.Create widget
- newButton = new QPushButton("New");
- addressEdit = new QLineEdit();
- goButton = new QPushButton("Go");
- // 2.Set property
- addressEdit.getSwingWidget().setColumns(10);
- // 3.Connect signal-slot
- connect(newButton, QPushButton.CLICKED, this, NEW_BUTTON_CLICKED);
- connect(addressEdit, QLineEdit.RETURN_PRESSED, this, HANDLE_GO_TO_ADDRESS);
- connect(goButton, QPushButton.CLICKED, this, HANDLE_GO_TO_ADDRESS);
- // 4.Add to layout
- getSwingWidget().add(newButton.getSwingWidget());
- getSwingWidget().add(addressEdit.getSwingWidget());
- getSwingWidget().add(goButton.getSwingWidget());
- }
- public void handleGoToAddress() {
- emit(GO_TO_ADDRESS, addressEdit.getSwingWidget().getText(), "test string");
- }
- }
- public class TabBar extends JTabbedPane {
- /**
- * SLOT
- */
- public static final String HANDLE_NEW_TAB = "handleNewTab()";
- public static final String HANDLE_GO_TO_SITE = "goToSite(String,String)";
- public TabBar() {
- handleNewTab();
- }
- public void handleNewTab() {
- WebView tab = new WebView();
- add("blank", tab);
- }
- public void goToSite(String url, String testStr) {
- System.out.println("Receive url: " + url + ", " + testStr);
- WebView tab = (WebView) getSelectedComponent();
- tab.load(url);
- }
- }
- public class MainWindow extends JFrame {
- public static void main(String[] args) {
- JFrame window = new MainWindow();
- window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- window.setSize(320, 340);
- window.setVisible(true);
- }
- public MainWindow() {
- // 1.Create widget
- AddressBar addressBar = new AddressBar();
- TabBar tabBar = new TabBar();
- // 2.Set property
- // 3.Connect signal-slot
- QObject.connect(addressBar, AddressBar.NEW_BUTTON_CLICKED, tabBar, TabBar.HANDLE_NEW_TAB);
- QObject.connect(addressBar, AddressBar.GO_TO_ADDRESS, tabBar, TabBar.HANDLE_GO_TO_SITE);
- // 4.Add to layout
- GridBagLayout layout = new GridBagLayout();
- setLayout(layout);
- GridBagConstraints grid = new GridBagConstraints();
- grid.fill = GridBagConstraints.BOTH;
- grid.gridx = grid.gridy = 0;
- grid.weightx = 1.0;
- grid.weighty = 0.1;
- add(addressBar.getSwingWidget(), grid);
- grid.fill = GridBagConstraints.BOTH;
- grid.gridx = 0;
- grid.gridy = 1;
- grid.weightx = 1.0;
- grid.weighty = 0.9;
- add(tabBar, grid);
- }
- }
- @SuppressWarnings("serial")
- class WebView extends JEditorPane {
- public WebView() {
- setEditable(false);
- }
- public void load(final String url) {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- try {
- WebView.this.setPage(url);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- });
- }
- }
![](http://my.csdn.net/uploads/201206/04/1338820504_6210.png)
Java实现Qt的SIGNAL-SLOT机制的更多相关文章
- qt信号signal和槽slot机制
内容: 一.概述 二.信号 三.槽 四.信号与槽的关联 五.元对象工具 六.程序样例 七.应注意的问题 信号与槽作为QT的核心机制在QT编程中有着广泛的应用,本文介绍了信号与槽的一些基本概念.元对象工 ...
- QT窗体间传值总结之Signal&Slot
在写程序时,难免会碰到多窗体之间进行传值的问题.依照自己的理解,我把多窗体传值的可以使用的方法归纳如下: 1.使用QT中的Signal&Slot机制进行传值: 2.使用全局变量: 3.使用pu ...
- Qt的内存管理机制
当我们在使用Qt时不可避免得需要接触到内存的分配和使用,即使是在使用Python,Golang这种带有自动垃圾回收器(GC)的语言时我们仍然需要对Qt的内存管理机制有所了解,以更加清楚的认识Qt对象的 ...
- qt的signal和slot机制
signal和slot是QT中的一大特点 signal/slot是Qt对象以及其派生类对象之间的一种高效通信接口 用户可以将N多个信号和单个槽相连接, 或者将将N个槽和单个信号连接, 甚至是一个信号和 ...
- 详解 Qt 线程间共享数据(使用signal/slot传递数据,线程间传递信号会立刻返回,但也可通过connect改变)
使用共享内存.即使用一个两个线程都能够共享的变量(如全局变量),这样两个线程都能够访问和修改该变量,从而达到共享数据的目的. Qt 线程间共享数据是本文介绍的内容,多的不说,先来啃内容.Qt线程间共享 ...
- 【golang-GUI开发】qt之signal和slot(二)
上一篇文章里我们详细介绍了signal的用法. 今天我们将介绍slot的使用.在qt中slot和signal十分相像,这次我们将实现一个能显示16进制数字的SpinBox,它继承自QSpinbox并重 ...
- 【golang-GUI开发】qt之signal和slot(一)
想了很久,我决定还是先从signal和slot(信号槽)开始讲起. signal和slot大家一定不陌生,先看一段示例(选自文档): class Counter : public QObject { ...
- C++11实现Qt的信号槽机制
概述 Qt的信号槽机制是Qt的核心机制,按钮点击的响应.线程间通信等都是通过信号槽来实现的,boost里也有信号槽,但和Qt提供的使用接口很不一样,本文主要是用C++11来实现一个简单的信号槽,该信号 ...
- VJGUI消息设计-兼谈MFC、QT和信号/槽机制
星期六下午4点,还在公司加班.终于写完了下周要交工的一个程序. 郁闷,今天这几个小时写了有上千行代码吧?虽然大部分都是Ctrl-C+Ctrl-V,但还是郁闷. 作为一个有10年经验的MFC程序员,郁闷 ...
- Qt学习记录--02 Qt的信号槽机制介绍(含Qt5与Qt4的差异对比)
一 闲谈: 熟悉Window下编程的小伙伴们,对其消息机制并不陌生, 话说:一切皆消息.它可以很方便实现不同窗体之间的通信,然而MFC库将很多底层的消息都屏蔽了,尽管使用户更加方便.简易地处理消息,但 ...
随机推荐
- [置顶] Java Web开发教程来袭
Java Web,是用Java技术来解决相关web互联网领域的技术总和.web包括:web服务器和web客户端两部分.Java在客户端的应用有java applet不过现在使用的很少,Java在服务器 ...
- Netty源代码学习——Included transports(变速箱)
Transport API核心: Channel介面 类图表示Channel含有Pipeline和Config接口,pipeline上一节有所介绍. Channel是线程安全的,这表示在多线环境下操作 ...
- ||和 && 符号的赋值运用(转)
javascript “||”.“&&”的灵活运用 博客分类: Jquery javascript javascript中运用“||”.“&&”javascript 真 ...
- 1/8=1/a+1/b,a,b为自然数
#include "stdio.h" int main(){ int a; int b; for(a=1;a<1000;a++) { for(b=1;b<1000; ...
- enter 默认搜索
onkeydown=" if(event.keyCode==13) Search(); "
- jquery ajax异步调用
写程序的第一步都要知其然,至于知其所以然就要看个人的爱好了.下面说一下web开发中经常用的ajax. 这里是用的jquery框架实现的ajax异步调用.废话少说先上代码.(asp.net开发) var ...
- vs在winform中不给力哈-错误不提示
我的操作系统是windows Server 2008 x64,运行winform的时候,对Dictionary累加值.运行的时候,项目一闪而过,于是我在Project的Properties上选择运行的 ...
- IDEA SVN1.8 问题解决
转自 http://blog.jetbrains.com/idea/2013/12/subversion-1-8-and-intellij-idea-13/
- 怎样在官网上下载xcode7.2
其实我觉得还是有必要就这个写一篇论文的 以证明自己真的是个菜鸟 首先进入苹果开发者官网 https://developer.apple.com/ 选择 resource 然后 点击加号 然后下载就 ...
- corejava-chap01
<java是什么:>Programming language 程序语言Development environment 开发环境Application environment 应用环境Dep ...