qt学习之利用滑动条控制小乌龟速度(三)

程序:main_window.hpp:

/**
 * @file /include/gui/main_window.hpp
 *
 * @brief Qt based gui for gui.
 *
 * @date November 2010
 **/
#ifndef gui_MAIN_WINDOW_H
#define gui_MAIN_WINDOW_H

/*****************************************************************************
** Includes
*****************************************************************************/

#include <QtGui/QMainWindow>
#include "ui_main_window.h"
#include "qnode.hpp"

/*****************************************************************************
** Namespace
*****************************************************************************/

namespace gui {

//float angular_value = 0.0 ;
//float turtle_angular = 0.0;
/*****************************************************************************
** Interface [MainWindow]
*****************************************************************************/
/**
 * @brief Qt central, all operations relating to the view part here.
 */
class MainWindow : public QMainWindow {
Q_OBJECT

public:
	MainWindow(int argc, char** argv, QWidget *parent = 0);
	~MainWindow();

	void ReadSettings(); // Load up qt program settings at startup
	void WriteSettings(); // Save qt program settings when closing

	void closeEvent(QCloseEvent *event); // Overloaded function
	void showNoMasterMessage();
  float right_angular_value = 0 ;
  float right_linear_value = 0 ;
  float left_angular_value = 0 ;
  float left_linear_value = 0 ;
  float backward_angular_value = 0 ;
  float backward_linear_value = 0 ;
  float forward_angular_value = 0 ;
  float forward_linear_value = 0 ;
public Q_SLOTS:
	/******************************************
	** Auto-connections (connectSlotsByName())
	*******************************************/
	void on_actionAbout_triggered();
	void on_button_connect_clicked(bool check );
	void on_checkbox_use_environment_stateChanged(int state);

    /******************************************
    ** Manual connections
    *******************************************/
   void updateLoggingView(); // no idea why this can't connect automatically

private Q_SLOTS:
    void on_forward_clicked();

    void on_backward_clicked();

    void on_right_clicked();

    void on_left_clicked();

    void on_AngularSlider_valueChanged(int value);
    void on_AngularSlider_left_valueChanged(int value);

    void on_LinearSlider_backward_valueChanged(int value);

    void on_LinearSlider_forward_valueChanged(int value);

private:
	Ui::MainWindowDesign ui;
	QNode qnode;

};

}  // namespace gui

#endif // gui_MAIN_WINDOW_H

qnode.hpp:

/**
 * @file /include/gui/qnode.hpp
 *
 * @brief Communications central!
 *
 * @date February 2011
 **/
/*****************************************************************************
** Ifdefs
*****************************************************************************/

#ifndef gui_QNODE_HPP_
#define gui_QNODE_HPP_

/*****************************************************************************
** Includes
*****************************************************************************/

// To workaround boost/qt4 problems that won't be bugfixed. Refer to
//    https://bugreports.qt.io/browse/QTBUG-22829
#ifndef Q_MOC_RUN
#include <ros/ros.h>
#endif
#include <string>
#include <QThread>
#include <QStringListModel>


/*****************************************************************************
** Namespaces
*****************************************************************************/

namespace gui {
//float angular_value = 0 ;
//float turtle_angular = 0;

/*****************************************************************************
** Class
*****************************************************************************/
//float turtle_linear = 0.0;
class QNode : public QThread {
    Q_OBJECT

public:
	QNode(int argc, char** argv );
	virtual ~QNode();
  bool init();
  bool init(const std::string &master_url, const std::string &host_url);
  //void run();
  void forward();
  void backward();
  void right();
  void left();

  float right_turtle_angular = 0;
  float right_turtle_linear = 0;
  float left_turtle_angular = 0;
  float left_turtle_linear = 0;
  float backward_turtle_angular = 0;
  float backward_turtle_linear = 0;
  float forward_turtle_angular = 0;
  float forward_turtle_linear = 0;
	/*********************
	** Logging
	**********************/
	enum LogLevel {
	         Debug,
	         Info,
	         Warn,
	         Error,
	         Fatal
	 };

	QStringListModel* loggingModel() { return &logging_model; }
	void log( const LogLevel &level, const std::string &msg);

Q_SIGNALS:
	void loggingUpdated();
    void rosShutdown();

private:
	int init_argc;
	char** init_argv;
	ros::Publisher chatter_publisher;
    QStringListModel logging_model;


};

}  // namespace gui

#endif /* gui_QNODE_HPP_ */

qnode.cpp:

/**
 * @file /src/qnode.cpp
 *
 * @brief Ros communication central!
 *
 * @date February 2011
 **/

/*****************************************************************************
** Includes
*****************************************************************************/

#include <ros/ros.h>
#include <ros/network.h>
#include <string>
#include <std_msgs/String.h>
#include <sstream>
#include <geometry_msgs/Twist.h>
#include <QSlider>
#include "../include/gui/qnode.hpp"

/*****************************************************************************
** Namespaces
*****************************************************************************/

namespace gui {

/*****************************************************************************
** Implementation
*****************************************************************************/

QNode::QNode(int argc, char** argv ) :
  init_argc(argc),
	init_argv(argv)
  {

  }

QNode::~QNode() {

    if(ros::isStarted()) {
      ros::shutdown(); // explicitly needed since we use ros::start();
      ros::waitForShutdown();
    }
	wait();
}

bool QNode::init() {
	ros::init(init_argc,init_argv,"gui");
	if ( ! ros::master::check() ) {
		return false;
	}
	ros::start(); // explicitly needed since our nodehandle is going out of scope.
	ros::NodeHandle n;
	// Add your ros communications here.
  chatter_publisher = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 1);
	start();
	return true;
}

bool QNode::init(const std::string &master_url, const std::string &host_url) {
	std::map<std::string,std::string> remappings;
	remappings["__master"] = master_url;
	remappings["__hostname"] = host_url;
	ros::init(remappings,"gui");
	if ( ! ros::master::check() ) {
		return false;
	}
	ros::start(); // explicitly needed since our nodehandle is going out of scope.
	ros::NodeHandle n;
	// Add your ros communications here.
  chatter_publisher = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 1);
	start();
	return true;
}

void QNode::forward() {

ros::Rate loop_rate(1);
if( ros::ok() )
{
geometry_msgs::Twist msg;
msg.linear.x = forward_turtle_linear;
msg.angular.z = 0.0;
std::string forward_log ="I'm going forward, speed:";
//字符串转换并连接,参考:https://blog.csdn.net/wangshubo1989/article/details/50241899
std::string speed= static_cast<std::ostringstream*>( &(std::ostringstream() << forward_turtle_linear) )->str();
forward_log += speed;
log(Info,std::string(forward_log));
chatter_publisher.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
}
void QNode::backward() {
ros::Rate loop_rate(1);
if( ros::ok() )
{
geometry_msgs::Twist msg;
msg.linear.x = -backward_turtle_linear;
msg.angular.z = 0.0;
std::string backward_log ="I'm going backward, speed:";
//字符串转换并连接,参考:https://blog.csdn.net/wangshubo1989/article/details/50241899
std::string speed= static_cast<std::ostringstream*>( &(std::ostringstream() << backward_turtle_linear) )->str();
backward_log += speed;
log(Info,std::string(backward_log));
chatter_publisher.publish(msg);
ros::spinOnce();
loop_rate.sleep();

}
}
void QNode::left() {
ros::Rate loop_rate(1);
if ( ros::ok() )
{
geometry_msgs::Twist msg;
msg.linear.x = 0;
msg.angular.z =left_turtle_angular;
std::string left_log ="I'm turning left, speed:";
//字符串转换并连接,参考:https://blog.csdn.net/wangshubo1989/article/details/50241899
std::string speed= static_cast<std::ostringstream*>( &(std::ostringstream() << left_turtle_angular) )->str();
left_log += speed;
log(Info,std::string(left_log));

chatter_publisher.publish(msg);
 ros::spinOnce();
 loop_rate.sleep();

}
//std::cout << “Ros shutdown, proceeding to close the gui.” << std::endl;
//Q_EMIT rosShutdown(); // used to signal the gui for a shutdown (useful to roslaunch)
}
void QNode::right()
{
     ros::NodeHandle n;
    // Add your ros communications here.
    chatter_publisher = n.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel", 1);
    ros::Rate loop_rate(1);
    std::string right_log ="I'm turning right, speed:";
    //字符串转换并连接,参考:https://blog.csdn.net/wangshubo1989/article/details/50241899
    std::string speed= static_cast<std::ostringstream*>( &(std::ostringstream() << right_turtle_angular) )->str();
    right_log += speed;
    log(Info,std::string(right_log));

if ( ros::ok() )
  {
    geometry_msgs::Twist msg;
    msg.linear.x = 0;
    msg.angular.z = -right_turtle_angular;
    chatter_publisher.publish(msg);
    ros::spinOnce();
    loop_rate.sleep();
  }
}

/*void QNode::run() {
	ros::Rate loop_rate(1);
	int count = 0;
	while ( ros::ok() ) {

		std_msgs::String msg;
		std::stringstream ss;
		ss << "hello world " << count;
		msg.data = ss.str();
		chatter_publisher.publish(msg);
		log(Info,std::string("I sent: ")+msg.data);
		ros::spinOnce();
		loop_rate.sleep();
		++count;
	}
	std::cout << "Ros shutdown, proceeding to close the gui." << std::endl;
	Q_EMIT rosShutdown(); // used to signal the gui for a shutdown (useful to roslaunch)
}*/


void QNode::log( const LogLevel &level, const std::string &msg)
{
	logging_model.insertRows(logging_model.rowCount(),1);
	std::stringstream logging_model_msg;
	switch ( level ) {
		case(Debug) : {
				ROS_DEBUG_STREAM(msg);
				logging_model_msg << "[DEBUG] [" << ros::Time::now() << "]: " << msg;
				break;
		}
		case(Info) : {
				ROS_INFO_STREAM(msg);
				logging_model_msg << "[INFO] [" << ros::Time::now() << "]: " << msg;
				break;
		}
		case(Warn) : {
				ROS_WARN_STREAM(msg);
				logging_model_msg << "[INFO] [" << ros::Time::now() << "]: " << msg;
				break;
		}
		case(Error) : {
				ROS_ERROR_STREAM(msg);
				logging_model_msg << "[ERROR] [" << ros::Time::now() << "]: " << msg;
				break;
		}
		case(Fatal) : {
				ROS_FATAL_STREAM(msg);
				logging_model_msg << "[FATAL] [" << ros::Time::now() << "]: " << msg;
				break;
		}
	}
	QVariant new_row(QString(logging_model_msg.str().c_str()));
	logging_model.setData(logging_model.index(logging_model.rowCount()-1),new_row);
	Q_EMIT loggingUpdated(); // used to readjust the scrollbar
}

}  // namespace gui

main_window.cpp:

/**
 * @file /src/main_window.cpp
 *
 * @brief Implementation for the qt gui.
 *
 * @date February 2011
 **/
/*****************************************************************************
** Includes
*****************************************************************************/

#include <QtGui>
#include <QMessageBox>
#include <iostream>
#include <QSlider>
//#include <QObject>
#include "../include/gui/main_window.hpp"

/*****************************************************************************
** Namespaces
*****************************************************************************/

namespace gui {

using namespace Qt;

/*****************************************************************************
** Implementation [MainWindow]
*****************************************************************************/

MainWindow::MainWindow(int argc, char** argv, QWidget *parent)
	: QMainWindow(parent)
	, qnode(argc,argv)
{
	ui.setupUi(this); // Calling this incidentally connects all ui's triggers to on_...() callbacks in this class.
    QObject::connect(ui.actionAbout_Qt, SIGNAL(triggered(bool)), qApp, SLOT(aboutQt())); // qApp is a global variable for the application

    ReadSettings();
	setWindowIcon(QIcon(":/images/icon.png"));
	ui.tab_manager->setCurrentIndex(0); // ensure the first tab is showing - qt-designer should have this already hardwired, but often loses it (settings?).
    QObject::connect(&qnode, SIGNAL(rosShutdown()), this, SLOT(close()));

	/*********************
	** Logging
	**********************/
	ui.view_logging->setModel(qnode.loggingModel());
    QObject::connect(&qnode, SIGNAL(loggingUpdated()), this, SLOT(updateLoggingView()));

    /*********************
    ** Auto Start
    **********************/
    if ( ui.checkbox_remember_settings->isChecked() ) {
        on_button_connect_clicked(true);
    }
}

MainWindow::~MainWindow() {}

/*****************************************************************************
** Implementation [Slots]
*****************************************************************************/

void MainWindow::showNoMasterMessage() {
	QMessageBox msgBox;
	msgBox.setText("Couldn't find the ros master.");
	msgBox.exec();
    close();
}

/*
 * These triggers whenever the button is clicked, regardless of whether it
 * is already checked or not.
 */

void MainWindow::on_button_connect_clicked(bool check ) {
	if ( ui.checkbox_use_environment->isChecked() ) {
		if ( !qnode.init() ) {
			showNoMasterMessage();
		} else {
			ui.button_connect->setEnabled(false);
		}
	} else {
		if ( ! qnode.init(ui.line_edit_master->text().toStdString(),
				   ui.line_edit_host->text().toStdString()) ) {
			showNoMasterMessage();
		} else {
			ui.button_connect->setEnabled(false);
			ui.line_edit_master->setReadOnly(true);
			ui.line_edit_host->setReadOnly(true);
			ui.line_edit_topic->setReadOnly(true);
		}
	}
}


void MainWindow::on_checkbox_use_environment_stateChanged(int state) {
	bool enabled;
	if ( state == 0 ) {
		enabled = true;
	} else {
		enabled = false;
	}
	ui.line_edit_master->setEnabled(enabled);
	ui.line_edit_host->setEnabled(enabled);
	//ui.line_edit_topic->setEnabled(enabled);
}

/*****************************************************************************
** Implemenation [Slots][manually connected]
*****************************************************************************/

/**
 * This function is signalled by the underlying model. When the model changes,
 * this will drop the cursor down to the last line in the QListview to ensure
 * the user can always see the latest log message.
 */
void MainWindow::updateLoggingView() {
        ui.view_logging->scrollToBottom();
}

/*****************************************************************************
** Implementation [Menu]
*****************************************************************************/

void MainWindow::on_actionAbout_triggered() {
    QMessageBox::about(this, tr("About ..."),tr("<h2>PACKAGE_NAME Test Program 0.10</h2><p>Copyright Yujin Robot</p><p>This package needs an about description.</p>"));
}

/*****************************************************************************
** Implementation [Configuration]
*****************************************************************************/

void MainWindow::ReadSettings() {
    QSettings settings("Qt-Ros Package", "gui");
    restoreGeometry(settings.value("geometry").toByteArray());
    restoreState(settings.value("windowState").toByteArray());
    QString master_url = settings.value("master_url",QString("http://192.168.1.2:11311/")).toString();
    QString host_url = settings.value("host_url", QString("192.168.1.3")).toString();
    //QString topic_name = settings.value("topic_name", QString("/chatter")).toString();
    ui.line_edit_master->setText(master_url);
    ui.line_edit_host->setText(host_url);
    //ui.line_edit_topic->setText(topic_name);
    bool remember = settings.value("remember_settings", false).toBool();
    ui.checkbox_remember_settings->setChecked(remember);
    bool checked = settings.value("use_environment_variables", false).toBool();
    ui.checkbox_use_environment->setChecked(checked);
    if ( checked ) {
    	ui.line_edit_master->setEnabled(false);
    	ui.line_edit_host->setEnabled(false);
    	//ui.line_edit_topic->setEnabled(false);
    }
}

void MainWindow::WriteSettings() {
    QSettings settings("Qt-Ros Package", "gui");
    settings.setValue("master_url",ui.line_edit_master->text());
    settings.setValue("host_url",ui.line_edit_host->text());
    //settings.setValue("topic_name",ui.line_edit_topic->text());
    settings.setValue("use_environment_variables",QVariant(ui.checkbox_use_environment->isChecked()));
    settings.setValue("geometry", saveGeometry());
    settings.setValue("windowState", saveState());
    settings.setValue("remember_settings",QVariant(ui.checkbox_remember_settings->isChecked()));

}

void MainWindow::closeEvent(QCloseEvent *event)
{
	WriteSettings();
	QMainWindow::closeEvent(event);
}

}  // namespace gui


void gui::MainWindow::on_forward_clicked()
{
    qnode.forward();
}

void gui::MainWindow::on_backward_clicked()
{
    qnode.backward();
}

void gui::MainWindow::on_right_clicked()
{
  qnode.right();
}

void gui::MainWindow::on_left_clicked()
{
     qnode.left();
}


 //QObject::connect(ui.AngularSlider, SIGNAL(valueChanged(int)), this, SLOT(on_AngularSlider_valueChanged(int)));


void gui::MainWindow::on_AngularSlider_valueChanged(int right_slider_value)
{
    right_angular_value = right_slider_value*0.1;//slider 值0-100,转化为0-10弧度
     qnode.right_turtle_angular = right_angular_value;//将值传给qnode.cpp中turtle角速度
     std::cout<<"Angular Value: "<<right_angular_value<<std::endl;

}

void gui::MainWindow::on_AngularSlider_left_valueChanged(int left_slider_value)
{
  left_angular_value = left_slider_value*0.1;//slider 值0-100,转化为0-10弧度
     qnode.left_turtle_angular = left_angular_value;//将值传给qnode.cpp中turtle角速度
     std::cout<<"Angular Value: "<<left_angular_value<<std::endl;
}

void gui::MainWindow::on_LinearSlider_backward_valueChanged(int backward_slider_value)
{
  backward_linear_value = backward_slider_value;//slider
     qnode.backward_turtle_linear = backward_linear_value;//将值传给qnode.cpp中turtle角速度
     std::cout<<"Angular Value: "<<backward_linear_value<<std::endl;
}

void gui::MainWindow::on_LinearSlider_forward_valueChanged(int forward_slider_value)
{
  forward_linear_value = forward_slider_value;//slider
     qnode.forward_turtle_linear = forward_linear_value;//将值传给qnode.cpp中turtle角速度
     std::cout<<"Angular Value: "<<forward_linear_value<<std::endl;
}

在cmakelist中加入:(否则会有警告)
add_compile_options(-std=c++11)

参考文献:
https://blog.csdn.net/qq_30460905/article/details/84898515

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
可以使用Qt中的QSlider滑动控件和QColorDialog颜色选择对话框实现控制颜色值的功能。 首先,在Qt Designer中创建一个滑动和一个按钮,然后将它们放在窗口上。 接着,在Qt Creator中打开窗口类的头文件,添加如下代码: ```cpp #include <QSlider> #include <QColorDialog> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: QSlider *slider; QPushButton *button; QColor color; private slots: void setColor(); void onSliderValueChanged(int value); }; ``` 在MainWindow类的构造函数中,创建一个QSlider和一个QPushButton,并将它们添加到窗口中。设置滑动的最小值为0,最大值为255,初始值为0。将QPushButton的文本设置为“Choose Color”。 ```cpp MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { slider = new QSlider(Qt::Horizontal, this); slider->setMinimum(0); slider->setMaximum(255); slider->setValue(0); connect(slider, SIGNAL(valueChanged(int)), this, SLOT(onSliderValueChanged(int))); button = new QPushButton("Choose Color", this); connect(button, SIGNAL(clicked()), this, SLOT(setColor())); setCentralWidget(slider); setStatusBar(button); color = QColor(0, 0, 0); } ``` 在MainWindow类中添加两个私有槽函数setColor()和onSliderValueChanged(),用于设置颜色和响应滑动值的改变。 在setColor()函数中,使用QColorDialog对话框获取用户选择的颜色,并将其保存到color变量中。 ```cpp void MainWindow::setColor() { QColorDialog dialog(color, this); dialog.exec(); color = dialog.selectedColor(); } ``` 在onSliderValueChanged()函数中,将滑动的值转换为RGB颜色值,并将其设置为窗口的背景色。 ```cpp void MainWindow::onSliderValueChanged(int value) { int r = qRed(color.rgb()); int g = qGreen(color.rgb()); int b = qBlue(color.rgb()); if (slider == sender()) { r = value; } QColor newColor(r, g, b); setStyleSheet(QString("background-color: %1").arg(newColor.name())); } ``` 最后,在MainWindow类的析构函数中释放QSlider和QPushButton的内存。 ```cpp MainWindow::~MainWindow() { delete slider; delete button; } ``` 这样,就可以使用滑动控制颜色值了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值