效果图:

含义:停靠区窗口,和状态栏、标题栏是一个等级
属性:
setAllowedAreas(Qt::DockWidgetAreas areas)setFeatures(DockWidgetFeatures features)
含义:目录树
属性:
Columns页用于设计目录树的列,目录树可以有多个列。在设计器里可以添加、删除、移动列,设置列的文字、字体、前景色、背景色、文字对齐方式、图标等。
Items页面用于设计目录树的节点,可对每个节点设置属性,如文字、字体、图标等,特别是fags属性,可以设置节点是否可选、是否可编辑、是否有CheckBox等,还可以设置节点的CheckState。

private:
// 创建节点时用作type参数,自定义类型必须大于1000
enum treeItemType{
itTopItem = 1001,
itGroupItem,
itImageItem
};
enum treeColNum{
colItem=0,
colItemType=1
};
QLabel *LabFileName;// 显示状态栏文件名称
QPixmap curPixmap; // 当前图片
float pixRatio; // 当前图片比例
// 初始化目录树
void initTree();
void addFolderItem(QTreeWidgetItem *parItem,QString dirName); // 添加目录
QString getFinalFolderName(const QString &fullPathName); // 提取目录名称
void addImageItem(QTreeWidgetItem *parItem,QString aFilename); // 添加图片
void displayImage(QTreeWidgetItem *item); // 显示一个图片节点的图片
void changeItemCaption(QTreeWidgetItem *item); // 遍历改变节点标题
添加顶层节点
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 状态栏显示文件名
LabFileName = new QLabel("");
ui->statusBar->addWidget(LabFileName);
// 设置中心窗体
this->setCentralWidget(ui->scrollArea);
// 初始化目录树
initTree();
}
void MainWindow::initTree()
{
QString dataStr = "";
ui->treeWidget->clear(); // 清空目录树
QIcon icon;
icon.addFile(":/icons/icons/15.ico");
QTreeWidgetItem *item = new QTreeWidgetItem(MainWindow::itTopItem); //?
item->setIcon(MainWindow::colItem,icon); // 第一列图标
item->setText(MainWindow::colItem,"图片文件"); // 第一列文字
item->setText(MainWindow::colItemType,"type=itTopItem"); // 第二列文字
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsAutoTristate | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
item->setCheckState(colItem,Qt::Checked); // 第一列勾选
item->setData(MainWindow::colItem,Qt::UserRole,QVariant(dataStr)); //?
ui->treeWidget->addTopLevelItem(item);// 添加顶层节点
}
void() TreeWidgetItem::setData(int column,int role,const QVariant &value)如
item->setData(MainWindow:colItem,Qt::UserRole,QVariant (datastr));
它为节点的第1列,角色Qt:UserRole,设置了一个字符串数据dataStr.Qt:UserRole是枚举类型Qt:ItemDataRole中一个预定义的值。
定义3个函数
// 获取文件名称
QString MainWindow::getFinalFolderName(const QString &fullPathName)
{
return fullPathName.right(fullPathName.length()-fullPathName.lastIndexOf("/")-1);
}
// 添加节点函数
void MainWindow::addFolderItem(QTreeWidgetItem *parItem, QString dirName)
{
QIcon icon(":/icons/icons/open3.bmp");
QString NodeText = getFinalFolderName(dirName);
QTreeWidgetItem *item = new QTreeWidgetItem(MainWindow::itGroupItem); // 传入目录的节点类型type值1001
item->setIcon(colItem,icon);
item->setText(colItem,NodeText);
item->setText(colItemType,"type:itGroupItem");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsAutoTristate | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
item->setCheckState(colItem,Qt::Checked);
item->setData(colItem,Qt::UserRole,QVariant(dirName));
parItem->addChild(item); // 在父节点添加子节点
}
// action关联函数
void MainWindow::on_actAddFolder_triggered()
{
QString fullname = QFileDialog::getExistingDirectory();
if(!fullname.isEmpty()){
QTreeWidgetItem *parItem = ui->treeWidget->currentItem();
if(parItem){
addFolderItem(parItem,fullname);
}else {
// 创建弹窗
QMessageBox::critical(this, tr("危险弹窗"), tr("请选择目标节点"),QMessageBox::Save | QMessageBox::Discard, QMessageBox::Discard);
}
}
else {
return;
}
}
QFileDialog::getOpenFileNames函数可以实现添加多个文件
实现:
void MainWindow::addImageItem(QTreeWidgetItem *parItem, QString aFilename)
{
QIcon icon(":/icons/icons/31.ico");
QString NodeText = getFinalFolderName(aFilename);
QTreeWidgetItem *item;
item = new QTreeWidgetItem(MainWindow::itImageItem);
item->setIcon(colItem,icon);
item->setText(colItem,NodeText);
item->setText(colItemType,"type=itImageItem");
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsAutoTristate | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
item->setData(colItem,Qt::UserRole,QVariant(aFilename));
parItem->addChild(item); // 在父节点添加子节点
}
void MainWindow::on_actAddFiles_triggered()
{
QStringList files = QFileDialog::getOpenFileNames(this,"选择一个或者多个文件","","Images(*.jpg)");
if(files.isEmpty())
return;
QTreeWidgetItem *parItem,*item;
item = ui->treeWidget->currentItem();
if(item){
if(item->type()==itImageItem) // 当前节点是图片节点
parItem = item->parent();
else {
parItem=item;
}
for (int i = 0;i<files.size();++i) {
QString aFilename = files.at(i);
addImageItem(parItem,aFilename);
}
}else {
QMessageBox::critical(this, tr("危险弹窗"), tr("请选择目标节点"),QMessageBox::Save | QMessageBox::Discard, QMessageBox::Discard);
}
}
QTreeWidget会发出currentItemChanged信号
实现:
代码实现:
void MainWindow::on_treeWidget_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
{
Q_UNUSED(previous);
if(current==NULL)
return;
int var = current->type();
switch (var) {
case itTopItem:
ui->actAddFolder->setEnabled(true);
ui->actAddFiles->setEnabled(true);
ui->actDeleteItem->setEnabled(false);
break;
case itGroupItem:
ui->actAddFolder->setEnabled(true);
ui->actAddFiles->setEnabled(true);
ui->actDeleteItem->setEnabled(true);
break;
case itImageItem: // 当前选中为图片,不能添加子节点,显示图片
ui->actAddFolder->setEnabled(false);
ui->actAddFiles->setEnabled(true);
ui->actDeleteItem->setEnabled(true);
ui->actZoomFitH->setEnabled(true);
ui->actZoomFitW->setEnabled(true);
ui->actZoomIn->setEnabled(true);
ui->actZoomOut->setEnabled(true);
ui->actZoomRealSize->setEnabled(true);
displayImage(current);
break;
}
}
删除节点使用QTreeWidgetItem对象上的removeChild函数
实现:
代码实现:
void MainWindow::on_actDeleteItem_triggered()
{
QTreeWidgetItem *item = ui->treeWidget->currentItem();
QTreeWidgetItem *parItem = item->parent();
parItem->removeChild(item);
delete item; // 删除子节点的内存空间。removveChild只能从父节点中删除子节点,但不能移除子节点的内存空间。
}
使用递归调用
int topLevelItemCount():返回顶层节点个数。
QTree WidgetItemtopLevelItem(int index):返回序号为index的顶层节点。
int topLevelItemCount():返回顶层节点个数。
QTree WidgetItem*topLevelItem(int index):返回序号为index的顶层节点。
实现:
代码实现:
void MainWindow::on_actScanItems_triggered()
{
int cnt = ui->treeWidget->topLevelItemCount();
for(int i = 0;i<cnt;++i){
QTreeWidgetItem *item = ui->treeWidget->topLevelItem(i); // 顶层节点
changeItemCaption(item); // 调用【更改节点标题】函数
}
}
void MainWindow::changeItemCaption(QTreeWidgetItem *item)
{
// 节点标题前加*
QString str = "*" + item->text(colItem);
item->setText(colItem,str);
if(item->childCount()>0){
for (int i = 0;i<item->childCount();i++) {
changeItemCaption(item->child(i));
}
}
}
curPixmap是在MainWindow中定义的一个QPixmap类型的变量,用于操作图片。QPixmap:load(QString&cfileName)直接将一个图片文件载入。
实现:
这里还显示不了,还未写自适应高度显示action;
void MainWindow::displayImage(QTreeWidgetItem *item)
{
QString filename = item->data(colItem,Qt::UserRole).toString(); // 获取文件名,之前用setData存的数据
LabFileName->setText(filename); // 状态栏显示图片名称
curPixmap.load(filename); // 当前图片
on_actZoomFitH_triggered(); // 自适应高度显示
}
QPixmap存储图片数据,可以缩放图片,有以下几个函数。
变量curPixmap保存了图片的原始副本,要缩放只需调用curPixmap的相应函数,返回缩放后的图片副本。在界面上的一个标签LabPicture上显示图片,使用了QLabel的setPixmap(const QPixmap&)函数。
void MainWindow::on_actZoomFitH_triggered()
{
// 自适应高度显示
int H = ui->scrollArea->height(); // 获取当前滑动块的高度
int realH = curPixmap.height(); // 获取当前图片的高度
pixRatio = float(H)/realH; // 当前图片显示的比例(必须是浮点数)
QPixmap pix = curPixmap.scaledToHeight(H-30); // 图片缩放指定高度
ui->label->setPixmap(pix); // label标签显示图片
}
void MainWindow::on_actZoomFitW_triggered()
{
// 自适应宽度显示
int W = ui->scrollArea->width(); // 获取当前滑动块的高度
int realW = curPixmap.width(); // 获取当前图片的高度
pixRatio = float(W)/realW; // 当前图片显示的比例(必须是浮点数)
QPixmap pix = curPixmap.scaledToWidth(W-30); // 图片缩放指定高度
ui->label->setPixmap(pix); // label标签显示图片
}
void MainWindow::on_actZoomIn_triggered()
{
// 放大显示
pixRatio = pixRatio*1.2;
int w = pixRatio*curPixmap.width();
int h = pixRatio*curPixmap.height();
QPixmap pix = curPixmap.scaled(w,h);
ui->label->setPixmap(pix);
}
void MainWindow::on_actZoomOut_triggered()
{
// 缩小显示
pixRatio = pixRatio*0.8;
int w = pixRatio*curPixmap.width();
int h = pixRatio*curPixmap.height();
QPixmap pix = curPixmap.scaled(w,h);
ui->label->setPixmap(pix);
}
void MainWindow::on_actZoomRealSize_triggered()
{
// 实际大小
pixRatio = 1;
ui->label->setPixmap(curPixmap);
}
只写action按钮的动作,手动拖动dockWidget时按钮的状态不会改变,需要使用dockWidget上的信号;
隐藏发射信号visibilityChanged(bool)
浮动、停靠信号topLevelChanged(bool)
void MainWindow::on_actDockVisible_toggled(bool arg1)
{
ui->dockWidget->setVisible(arg1);
}
void MainWindow::on_actDockFloat_toggled(bool arg1)
{
ui->dockWidget->setFloating(arg1);
}
void MainWindow::on_dockWidget_topLevelChanged(bool topLevel)
{
ui->actDockFloat->setChecked(topLevel);
}
void MainWindow::on_dockWidget_visibilityChanged(bool visible)
{
ui->actDockVisible->setChecked(visible);
}
我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
我试图在索引页中创建一个超链接,但它没有显示,也没有给出任何错误。这是我的index.html.erb代码。ListingarticlesTitleTextssss我检查了我的路线,我认为它们也没有问题。PrefixVerbURIPatternController#Actionwelcome_indexGET/welcome/index(.:format)welcome#indexarticlesGET/articles(.:format)articles#indexPOST/articles(.:format)articles#createnew_articleGET/article
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c
目前,Itembelongs_toCompany和has_manyItemVariants。我正在尝试使用嵌套的fields_for通过Item表单添加ItemVariant字段,但是使用:item_variants不显示该表单。只有当我使用单数时才会显示。我检查了我的关联,它们似乎是正确的,这可能与嵌套在公司下的项目有关,还是我遗漏了其他东西?提前致谢。注意:下面的代码片段中省略了不相关的代码。编辑:不知道这是否相关,但我正在使用CanCan进行身份验证。routes.rbresources:companiesdoresources:itemsenditem.rbclassItemi
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决